安全分为 认证和授权,前边讲的都是认证,现在说授权。

前端业务系统的权限简单些,一般只区分是否登录,复杂点的还会区分 VIP用户等简单的角色,权限规则基本不变。

后台系统比较复杂,角色众多,权限随着业务不断变化。

 1,用代码控制简单的权限

直接在配置类 BrowserSecurityConfig   extends   WebSecurityConfigurerAdapter 的configure方法里

http //--------------授权相关的配置 ---------------------
            .authorizeRequests()  
                // /authentication/require:处理登录,securityProperties.getBrowser().getLoginPage():用户配置的登录页
                .antMatchers(SecurityConstants.DEFAULT_UNAUTHENTICATION_URL, 
                securityProperties.getBrowser().getLoginPage(),//放过登录页不过滤,否则报错
                SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_MOBILE,
                SecurityConstants.SESSION_INVALID_PAGE,
                SecurityConstants.DEFAULT_VALIDATE_CODE_URL_PREFIX+"/*")//验证码
                .permitAll() //-------上边的不用授权也允许访问------
                //~=========简单的权限控制,只区分是否登录的情况可以配置在这里=======
                //  /user 的post请求需要ADMIN权限
                .antMatchers("/user/*").hasRole("ADMIN")
                .anyRequest()        //任何请求
                .authenticated()    //都需要身份认证

一行红色部分配置就可以了,意思是 /user/* 的所有请求需要有ADMIN 权限,如果是Rest风格的服务,只需要配置成 antMatchers(HttpMethod.POST,"/user/*").hasRole("ADMIN") 格式即可。

这个权限在UserDetailsService 的loadUserByUsername方法返回的user的权限集合里定义。格式是ROLE_ADMIN( ROLE_权限名称,ADMIN和匹配器里一致)(这个格式具体在ExpressionUrlAuthorizationConfigurer里)

 

 

private SocialUserDetails buildUser(String userId) {
        String password = passwordEncoder.encode("123456");
        System.err.println("加密后密码:  "+password);
        //参数:用户名|密码|是否启用|账户是否过期|密码是否过期|账户是否锁定|权限集合
        return new SocialUser(userId,password,true,true,true,true,
                //工具类 将字符串转换为权限集合,ROLE_角色 是spring要求的权限格式
                AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN"));
    }

 

再说一个过滤器,AnonymousAuthenticationFilter,这个过滤器就是判断前边的过滤器是否认证成功,如果没有认证成功,就创建一个默认的用户创建一个Authentication 做登录。具体代码看其源码。

SpringSecurity 授权相关类

 ==============================================================================================================================

控制复杂权限:基于rbac

自定义查询权限的类根据用户名查询用户的权限

package com.imooc.security.rbac;

import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

@Component("rbacService")
public class RbacServiceImpl implements RbacService {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();
    
    @Override
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        
        Object principal = authentication.getPrincipal();
        
        boolean hasPermission = false;
        
        if(principal instanceof UserDetails){
            
            String username = ((UserDetails)principal).getUsername();
            
            //读取用户所有权限的url,需要查询数据库
            Set<String> urls = new HashSet<>();
            urls.add("/user/*");
            
            for(String url : urls){
                if(antPathMatcher.match(url, request.getRequestURI())){
                    hasPermission = true ;
                    break ;
                }
            }
        }
        return hasPermission;
    }

}

配置,注意,授权的配置要配置在免登录就能访问的服务器的最后

 github:https://github.com/lhy1234/spring-security

 

 

欢迎关注个人公众号一起交流学习: