Spring security 分为两个部分

  1. 登陆认证
  2. 权限认证

登陆认证 其实就是就是登陆注册,然后获取登陆凭证的问题
操作如下

  1. 登陆账号密码,通过账号查询出用户数据,然后密码进行比对
  2. 比对成功,将用户信息插入 SecurityContextHolder 中
    SecurityContextHolder 有数据,UsernamePasswordAuthenticationFilter 就认为用户过了登陆认证,则不在登陆拦截
@AutoConfiguration
// 需要配置权限认证的其实就只有这一段,添加这个注解就OK了
// 就是这个 prePostEnabled=true,有了它,就可以在方法上写注解来做权限验证
// 例如:@PreAuthorize("@实例类.方法('参数')")
// example:@PreAuthorize("@ss.hasPermission('true')")
// 具体看下面的权限验证部分
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class YudaoWebSecurityConfigurerAdapter {
... 省略其他代码

	/**
     * 配置 URL 的安全配置
     * 
     * 注意:
     * 其实这里主要是设置是否需要登录的
     * 权限验证其实不在这个地方
     *
     * anyRequest          |   匹配所有请求路径
     * access              |   SpringEl表达式结果为true时可以访问
     * anonymous           |   匿名可以访问
     * denyAll             |   用户不能访问
     * fullyAuthenticated  |   用户完全认证可以访问(非remember-me下自动登录)
     * hasAnyAuthority     |   如果有参数,参数表示权限,则其中任何一个权限可以访问
     * hasAnyRole          |   如果有参数,参数表示角色,则其中任何一个角色可以访问
     * hasAuthority        |   如果有参数,参数表示权限,则其权限可以访问
     * hasIpAddress        |   如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
     * hasRole             |   如果有参数,参数表示角色,则其角色可以访问
     * permitAll           |   用户可以任意访问
     * rememberMe          |   允许通过remember-me登录的用户访问
     * authenticated       |   用户登录后可访问
     */
    @Bean
    protected SecurityFilterChain configure(HttpSecurity httpSecurity) throws Exception {
		// 设置每个请求的权限
        httpSecurity
                // ①:全局共享规则
                .authorizeRequests()
                // permitAll 关键点 这里就是意思要不要登陆
                .antMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll()
                // ③:兜底规则,必须认证
                .anyRequest().authenticated()
        ;

        // 添加 JWT Filter
        httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        return httpSecurity.build();
    }
... 省略其他代码

权限验证

@AutoConfiguration
@EnableConfigurationProperties(SecurityProperties.class)
public class YudaoSecurityAutoConfiguration {
    @Resource
    private SecurityProperties securityProperties;

    /**
     * Spring Security 加密器
     * 考虑到安全性,这里采用 BCryptPasswordEncoder 加密器
     *
     * @see <a href="http://stackabuse.com/password-encoding-with-spring-security/">Password Encoding with Spring Security</a>
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 认证失败处理类 Bean
     */
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return new AuthenticationEntryPointImpl();
    }

    /**
     * 权限不够处理器 Bean
     */
    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return new AccessDeniedHandlerImpl();
    }

    /**
     * Token 认证过滤器 Bean
     */
    @Bean
    public TokenAuthenticationFilter authenticationTokenFilter(GlobalExceptionHandler globalExceptionHandler) {
        return new TokenAuthenticationFilter(securityProperties, globalExceptionHandler);
    }

    @Bean("ss") // 使用 Spring Security 的缩写,方便使用
    public SecurityFrameworkService securityFrameworkService() {
        return new SecurityFrameworkServiceImpl();
    }

}

权限验证

上面配置已经开启了注解 @PreAuthorize 来做权限验证
看懂这里就简单了。举例如下
例如:@PreAuthorize(“@实例类.方法(‘参数’)”)
example:@PreAuthorize(“@ss.hasPermission(‘true’)”)
这里实现就是:

  1. 开启注解@PreAuthorize做权限校验
  2. 注入名称为 ss 的bean
  3. 写入方法 hasPermission,方法返回true=权限校验通过,false=权限校验不通过

注入名称为 ss 的bean 如下:

// 创建一个权限校验类
@AllArgsConstructor
public class SecurityFrameworkServiceImpl {

    @Override
    public boolean hasPermission(String permission) {
        return permission.equals("true");
    }

    @Override
    public boolean hasAnyPermissions(String... permissions) {
        return false;
    }

    @Override
    public boolean hasRole(String role) {
        return false;
    }

    @Override
    public boolean hasAnyRoles(String... roles) {
        return false;
    }

    @Override
    public boolean hasScope(String scope) {
        return false;
    }

    @Override
    public boolean hasAnyScopes(String... scope) {
        return false;
    }
}
// 实例化 权限校验类,并注入spring容器中
@Bean("ss")
public SecurityFrameworkService securityFrameworkService() {
    return new SecurityFrameworkServiceImpl();
}

到这里就结束了!
@PreAuthorize(“@ss.hasPermission(‘true’)”)
@PreAuthorize 开启校验
调用ss实例类中的hasPermission方法
返回结果为true=权限通过,false=权限不通过