Spring Security 5.0.x ----springmvc学习笔记


一、环境配置

1.导入依赖


    5.0.5.RELEASE


    org.springframework.security
    spring-security-web
    ${spring.security.version}


    org.springframework.security
    spring-security-config
    ${spring.security.version}

2.配置web.xml

注意filter和filter-mapping 以及servlet的顺序(在idea中会有放置提示)

filter-->filter-mapping-->listener-->servlet-->servlet-mapping



  
  springSecurityFilterChain
  org.springframework.web.filter.DelegatingFilterProxy


  springSecurityFilterChain
  /*

3.Spring Security要求提供SpringSecurityUserService ,并且实现UserDetailService接口

这里的SpringSecurityUserService后面在xml中需要配置进去。我这里使用的Dubbo远程请求数据库获取用户信息。

3.1 UserDetails

UserDetails里面存储的是用户信息以及用户拥有的角色和权限信息
//权限和角色信息都将存储在这个集合里面
Collection<? extends GrantedAuthority> getAuthorities(); String getPassword(); String getUsername();

3.2 GrantedAuthority(已授予的权限)

GrantedAuthority接口的实现类SimpleGrantedAuthority,在构建SimpleGrantedAuthority对象的时候,存放角色和权限的字符串,而且是需要带有前缀的字符串。

角色表

    权限表

角色能不能不带"ROLE_"前缀?

Spring security在check权限的时候是比较的字符串信息,比如它有个表达式hasRole("ADMIN")。那它实际上查询的是用户权限集合中是否存在字符串"ROLE_ADMIN"。如果你从角色表中取出用户所拥有的角色时不加上"ROLE_"前缀,那验证的时候就匹配不上了。所以角色信息存储的时候可以没有"ROLE_"前缀,但是包装成GrantedAuthority对象的时候必须要有。

具体的解释请参考https://www.cnblogs.com/longfurcat/p/9417422.html

@Component
public class SpringSecurityUserService implements UserDetailsService {

    @Reference //注意:此处要通过dubbo远程调用用户服务
    private UserService userService;

    /**
     *根据用户名获取用户信息
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user=userService.findByUserName(username);
        if(user==null){
            return null;
        }
//        springsecurity将所有的角色和权限都存储在GrantedAuthority中
//        ,比对字符串,所以权限角色的字符串应该必须带有Role或者代表权限的前缀
//        GrantedAuthority已授予的权限
        ArrayList list = new ArrayList<>();
        Set roles = user.getRoles();
        for (Role role : roles) {
//            授予角色 带前缀的字符串集合
            list.add(new SimpleGrantedAuthority(role.getKeyword()));
//            授予权限
            Set permissions = role.getPermissions();
            for (Permission permission : permissions) {
                list.add(new SimpleGrantedAuthority(permission.getKeyword()));
            }
        }
        UserDetails userDetails = new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(), list);
        return userDetails;
    }
}

4. spring-security.xml配置

<?xml version="1.0" encoding="UTF-8"?>


在springmvc.xml中引入spring-security.xml文件


5. 注解使用权限控制

@PreAuthorize("hasAuthority('CHECKITEM_ADD')")//权限校验

6. 获取Spring Security上下文对象中存储的用户信息

    try{
            org.springframework.security.core.userdetails.User user =
                    (org.springframework.security.core.userdetails.User)
                            SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            return new Result(true, MessageConstant.GET_USERNAME_SUCCESS,user.getUsername());
        }catch (Exception e){
            return new Result(false, MessageConstant.GET_USERNAME_FAIL);
        }