网站首页   文章专栏   Spring Security 之自定义UserDetails
Spring Security 之自定义UserDetails
原创 2020-02-16 23:45 ApeNixX 146浏览 SpringBoot

Spring Security(以下简称SS)中默认存在一个org.springframework.security.core.userdetails.UserDetails类,该类是SS内置的,提供了几个简单的属性,如userName,password,enabled等等,但这些属性不能完全适应我们现在的系统,所有一般需要自定义自己的UserDetails。自定义UserDetails需要继承SS内置的UserDetails,之所以继承内置的UserDetails,是因为在SS中可以通过SecurityContextHolder取得用户凭证和用户所有的信息,用户信息都存放在系统内置的UserDetails中,如果继承之后,即可进行向下转型,变成我们自己的定义的UserDetails了。

以下自定义的CustomerUserDetails中加入了用户基本信息,用户角色,用户权限等等,假设我需要在用户登录之后就加载这些用户关联的信息,那么加入UserDetails之后,在任何位置就能通过SecurityContextHolder取到了。

原来的用户信息是实现的springsecurity的接口org.springframework.security.userdetails.UserDetails 实现类为org.springframework.security.userdetails.User只放了username,password,权限列表等信息在session中,我们的扩展是要将user的头像放在session中,扩展User对象如下:

package com.apenixx.blog.service.security;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

import java.util.Collection;

/**
* @Author ApeNixX
* @Date 2020/2/3 20:58
* @Version 1.0
* @Describe
*/
public class CustomerUserDetails extends User {
  private  String avatarImgUrl;
  public CustomerUserDetails(String avatarImgUrl,String username, String password, Collection<? extends GrantedAuthority> authorities) {
      super(username, password, authorities);
      this.avatarImgUrl=avatarImgUrl;
  }

  public String getAvatarImgUrl() {
      return avatarImgUrl;
  }

  public void setAvatarImgUrl(String avatarImgUrl) {
      this.avatarImgUrl = avatarImgUrl;
  }
}

原来的UserDetailServiceImpl.java修改如下:
package com.apenixx.blog.service.security;

import com.apenixx.blog.mapper.UserMapper;
import com.apenixx.blog.model.Role;
import com.apenixx.blog.model.User;
import com.apenixx.blog.service.UserService;
import com.apenixx.blog.utils.TimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author ApeNixX
 * @Date 2020/1/19 18:45
 * @Version 1.0
 * @Describe 用户登录处理
 */
public class CustomUserServiceImpl implements UserDetailsService {

    @Autowired
    UserMapper userMapper;
    @Autowired
    UserService userService;
    @Override
    public UserDetails loadUserByUsername(String phone) throws UsernameNotFoundException {
       User user = userMapper.getUsernameAndRolesByPhone(phone);

        if(user == null){
            throw  new UsernameNotFoundException("用户不存在");
        }

        TimeUtil timeUtil = new TimeUtil();
        String recentlyLanded = timeUtil.getFormatDateForSix();
        userService.updateRecentlyLanded(user.getUsername(), recentlyLanded);

        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for(Role role : user.getRoles()){
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }

        //调用扩展后的CustomerUserDetails,这样就将avatarImgUrl属性扩展并交给springsecurity存放到session了
        if (user.getStatus()==0){
            CustomerUserDetails userdetail = new CustomerUserDetails(user.getAvatarImgUrl(),
                    user.getUsername(), user.getPassword(),authorities);
            return userdetail;
        }else {
            return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),false,false,false,false,authorities);
        }

//        return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),authorities);

    }
}

在前端页面显示

引入SpringSecurity标签

<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

通过${session.SPRING_SECURITY_CONTEXT.authentication.principal.avatarImgUrl}即可获得刚刚扩展的用户头像信息

<li sec:authorize="hasAnyRole('ROLE_USER')" class="layui-nav-item">
                <a href="javascript:;" class="blog-user">
                   <img th:src="@{${session.SPRING_SECURITY_CONTEXT.authentication.principal.avatarImgUrl}}" />
                    <span sec:authentication="name"></span> 
                </a>
                <dl class="layui-nav-child">
                    <dd><a th:href="@{/user/user}">基本资料</a></dd>
                    <dd><a class="news" th:href="@{/user/user}">我的消息</a></dd>
                    <dd><a th:href="@{/user/user}">安全设置</a></dd>
                    <dd sec:authorize="hasAnyRole('ROLE_SUPERADMIN','ROLE_ADMIN')"><a th:href="@{/admin/index}">后台管理</a></dd>
                    <dd><a th:href="@{/logout}">退出登录</a></dd>
                </dl>
                </li>
效果如下

版权声明:本文由ApeNixX原创出品,转载请注明出处!

本文链接:http://www.apenixx.top/article/details/1581867904


  SpringSecurity 

赞助本站,网站的发展离不开你们的支持!
来说两句吧
最新评论
  • 不落阁
    不落阁
    我为大家做了模拟留言与回复!试试吧!

    Absolutely
    Absolutely这是用户回复内容

    2017-03-18 18:26回复

    Absolutely
    Absolutely 回复 不落阁这是第二个用户回复内容

    2017-03-18 18:26回复