【转载】spring-security-oauth2 (二十七) Spring Security 权限表达式

权限表达式

通过源码分析可知,最终的配置都会转成ExpressionUrlAuthorizationConfigurer.AuthorizedUrl并进行投票决定。

常见表达式如下:

如何写联合表达式呢?就是既满足A条件,也满足B条件

.antMatchers("xx").access("hasRole('ROLE_USER') and hasRole('ROLE_SUPER')")

 这个都是spring自己的权限表达式,那么我们是否可以自定义实现自己的权限规则呢?可以的!这个我们下一章再看怎么实现。

 

权限业务配置分离

如何将权限模块配置和业务模块配置想分离呢?因为权限模块并不清楚业务模块的权限拦截规则。

实现思路如下:

  1. 提供AuthorizeConfigProvider接口,提供权限设置
  2. 权限模块的通用配置实现该接口,然后进行配置,业务模块按需也实现该接口进行配置
  3. 最后使用 AuthorizeConfigManager类来管理所有的AuthorizeConfigProvider实现
  4. 拿到所有的配置后,进行统一设置

代码实现如下:

权限控制接口及实现 


 
 
  1. package com.rui.tiger.auth.core.authorize;
  2. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  3. import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
  4. /**
  5. * 自定义权限控制接口
  6. * @author CaiRui
  7. * @date 2019-05-06 12:02
  8. */
  9. public interface AuthorizeConfigProvider {
  10. /**
  11. * @param config
  12. * @return 返回的boolean表示配置中是否有针对anyRequest的配置。在整个授权配置中,
  13. * 应该有且仅有一个针对anyRequest的配置,如果所有的实现都没有针对anyRequest的配置,
  14. * 系统会自动增加一个anyRequest().authenticated()的配置。如果有多个针对anyRequest
  15. * 的配置,则会抛出异常。
  16. */
  17. boolean config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config);
  18. }

通用权限设置


 
 
  1. package com.rui.tiger.auth.core.authorize;
  2. import com.rui.tiger.auth.core.properties.SecurityConstants;
  3. import com.rui.tiger.auth.core.properties.SecurityProperties;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.core.annotation.Order;
  7. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  8. import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
  9. import org.springframework.stereotype.Component;
  10. /**
  11. * 通用权限接口配置管理
  12. * @author CaiRui
  13. * @date 2019-05-06 12:08
  14. */
  15. @Component
  16. @Slf4j
  17. @Order(Integer.MIN_VALUE)
  18. public class CommonAuthorizeConfigProvider implements AuthorizeConfigProvider {
  19. @Autowired
  20. private SecurityProperties securityProperties;
  21. @Override
  22. public boolean config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
  23. config.antMatchers(
  24. SecurityConstants.DEFAULT_UNAUTHENTICATION_URL, //权限认证
  25. SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_MOBILE, //手机
  26. SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_OPENID, //openId
  27. securityProperties.getBrowser().getLoginPage(), //登录页面
  28. SecurityConstants.DEFAULT_VALIDATE_CODE_URL_PREFIX+ "/*", // /captcha/* 验证码放行
  29. securityProperties.getBrowser().getSignupUrl(),
  30. securityProperties.getBrowser().getLoginOut(),
  31. securityProperties.getBrowser().getSession().getInvalidSessionUrl()
  32. ).permitAll(); //放行
  33. return false;
  34. }
  35. }

业务模块权限设置


 
 
  1. package com.rui.tiger.auth.demo.security;
  2. import com.rui.tiger.auth.core.authorize.AuthorizeConfigProvider;
  3. import org.springframework.core.annotation.Order;
  4. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  5. import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
  6. import org.springframework.stereotype.Component;
  7. /**
  8. * 业务模块权限配置实现
  9. * @author CaiRui
  10. * @date 2019-05-06 12:16
  11. */
  12. @Component
  13. @Order(Integer.MAX_VALUE)
  14. public class DemoAuthorizeConfigProvider implements AuthorizeConfigProvider {
  15. @Override
  16. public boolean config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
  17. config.antMatchers(
  18. "/user/regist", // 注册请求
  19. "/error",
  20. "/connect/*",
  21. "/auth/*",
  22. "/signin",
  23. "/social/signUp", // app注册跳转服务
  24. "/swagger-ui.html",
  25. "/swagger-ui.html/**",
  26. "/webjars/**",
  27. "/swagger-resources/**",
  28. "/v2/**"
  29. ).permitAll();
  30. /*
  31. 利用@Order注解实现CommonAuthorizeConfigProvider中的放行路径不需要自定义权限验证
  32. */
  33. config.anyRequest()
  34. .access( "@rbacService.hasPermission(request,authentication)");
  35. return true;
  36. }
  37. }

权限接口管理器及实现


 
 
  1. package com.rui.tiger.auth.core.authorize;
  2. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  3. import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
  4. /**
  5. * 权限控制接口持有管理者
  6. * @author CaiRui
  7. * @date 2019-05-06 12:05
  8. */
  9. public interface AuthorizeConfigManager {
  10. void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config);
  11. }

 
 
  1. package com.rui.tiger.auth.core.authorize;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  4. import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
  5. import org.springframework.stereotype.Component;
  6. import java.util.List;
  7. import java.util.Set;
  8. /**
  9. * @author CaiRui
  10. * @date 2019-05-06 12:12
  11. */
  12. @Component
  13. public class DefaultAuthorizeConfigManager implements AuthorizeConfigManager {
  14. //有依赖顺序 通过@Order控制 不用set
  15. @Autowired
  16. private List<AuthorizeConfigProvider> providers;
  17. @Override
  18. public void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
  19. boolean existAnyRequestConfig = false;
  20. String existAnyRequestConfigName = null;
  21. for (AuthorizeConfigProvider authorizeConfigProvider : providers) {
  22. boolean currentIsAnyRequestConfig = authorizeConfigProvider.config(config);
  23. if (existAnyRequestConfig && currentIsAnyRequestConfig) {
  24. throw new RuntimeException( "重复的anyRequest配置:" + existAnyRequestConfigName + ","
  25. + authorizeConfigProvider.getClass().getSimpleName());
  26. } else if (currentIsAnyRequestConfig) {
  27. existAnyRequestConfig = true;
  28. existAnyRequestConfigName = authorizeConfigProvider.getClass().getSimpleName();
  29. }
  30. }
  31. if(!existAnyRequestConfig){
  32. config.anyRequest().authenticated();
  33. }
  34. }
  35. }

浏览器模块配置进行调整(app模块同理),就是将原来的配置抽离出去。


 
 
  1. @Override
  2. protected void configure(HttpSecurity http) throws Exception {
  3. /**
  4. * 表单密码配置
  5. */
  6. applyPasswordAuthenticationConfig(http);
  7. http
  8. .apply(captchaSecurityConfig)
  9. .and()
  10. .apply(smsAuthenticationSecurityConfig)
  11. .and()
  12. .apply(tigerSpringSocialConfigurer)
  13. .and()
  14. .rememberMe()
  15. .tokenRepository(persistentTokenRepository())
  16. .tokenValiditySeconds(securityProperties.getBrowser().getRemberMeSeconds())
  17. .userDetailsService(userDetailsService)
  18. .and()
  19. .sessionManagement()
  20. .invalidSessionStrategy(invalidSessionStrategy) //session失效策略
  21. .maximumSessions(securityProperties.getBrowser().getSession().getMaximumSessions()) //最大session并发数
  22. .maxSessionsPreventsLogin(securityProperties.getBrowser().getSession().isMaxSessionsPreventsLogin()) //true达到并发数后阻止登录,false 踢掉之前的登录
  23. .expiredSessionStrategy(sessionInformationExpiredStrategy) //并发策略
  24. .and()
  25. .and()
  26. .logout()
  27. .logoutUrl( "/loginOut") //默认logout
  28. //.logoutSuccessUrl("") url和Handler只能配置一个
  29. .logoutSuccessHandler(tigerLogoutSuccessHandler)
  30. .deleteCookies( "JSESSIONID") //清楚cook键值
  31. .and()
  32. .csrf().disable();
  33. //配置管理
  34. authorizeConfigManager.config(http.authorizeRequests());
  35. }

 

文章转载至:https://blog.csdn.net/ahcr1026212/article/details/89875404

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值