SpringSecurityOAuth2(4)根据请求URI动态权限判断

GitHub地址

码云地址

一般我们通过@PreAuthorize("hasRole('ROLE_USER')") 注解,以及在HttpSecurity配置权限需求等来控制权限。在这里,我们基于请求的URI来控制访问权限,并且可以使用注解来控制权限访问。

新建一个资源项目,配置资源服务。 首先 自定义一个权限认证MySecurityAccessDecisionManager 继承AccessDecisionManager接口,重写 decide方法, 并且复制默认权限验证AbstractAccessDecisionManager的剩余两个方法(实现注解控制的重点)。用户具有的权限在认证服务器中已经自定义了。

1/** 2 * @Description 自定义权限认证,获取url判断是否有权限 3 * @Author wwz 4 * @Date 2019/08/01 5 * @Param 6 * @Return 7 */ 8@Component 9public class MySecurityAccessDecisionManager implements AccessDecisionManager { 10 11 private List<AccessDecisionVoter<? extends Object>> decisionVoters; 12 13 @Override 14 public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { 15 String requestUrl = ((FilterInvocation) object).getRequest().getMethod() + ((FilterInvocation) object).getRequest().getRequestURI(); 16// System.out.println("requestUrl>>" + requestUrl); 17 18 // 当前用户所具有的权限 19 Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); 20// System.out.println("authorities=" + authorities); 21 for (GrantedAuthority grantedAuthority : authorities) { 22 if (grantedAuthority.getAuthority().equals(requestUrl)) { 23 return; 24 } 25 if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) { 26 return; 27 } 28 29 } 30 throw new AccessDeniedException("无访问权限"); 31 } 32 33 /** 34 * 复制默认方法,使得@PreAuthorize("hasRole('ROLE_ADMIN')") 可用 35 */ 36 @Override 37 public boolean supports(ConfigAttribute attribute) { 38 for (AccessDecisionVoter voter : this.decisionVoters) { 39 if (voter.supports(attribute)) { 40 return true; 41 } 42 } 43 return false; 44 } 45 46 @Override 47 public boolean supports(Class<?> clazz) { 48 for (AccessDecisionVoter voter : this.decisionVoters) { 49 if (!voter.supports(clazz)) { 50 return false; 51 } 52 } 53 return true; 54 } 55}

在资源服务配置的httpSecurity中重写并注入:

1/** 2 * @Description 资源认证 3 * @Author wwz 4 * @Date 2019/08/01 5 * @Param 6 * @Return 7 */ 8@Configuration 9@EnableResourceServer 10@EnableGlobalMethodSecurity(prePostEnabled = true) // 启用注解权限配置 11public class MySecurityResourceServerConfig extends ResourceServerConfigurerAdapter { 12 13 @Autowired 14 private RedisConnectionFactory connectionFactory; 15 16 @Bean 17 public TokenStore tokenStore() { 18 RedisTokenStore redis = new RedisTokenStore(connectionFactory); 19 return redis; 20 } 21 22 @Resource 23 private MyAccessDeniedHandler accessDeniedHandler; // 无权访问处理器 24 25 @Resource 26 private MyTokenExceptionEntryPoint tokenExceptionEntryPoint; // token失效处理器 27 28 @Resource 29 private MySecurityAccessDecisionManager accessDecisionManager; //权限判断 30 31 @Override 32 public void configure(HttpSecurity http) throws Exception { 33 http 34 .csrf().disable() 35 .exceptionHandling().authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED)) 36 .and() 37 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) // 另外,如果不设置,那么在通过浏览器访问被保护的任何资源时,每次是不同的SessionID,并且将每次请求的历史都记录在OAuth2Authentication的details的中 38 .and() 39 .authorizeRequests().antMatchers("/actuator/health").permitAll().anyRequest().authenticated() // httpSecurity 放过健康检查,其他都需要验证 设置了.anyRequest().authenticated()才回进入自定义的权限判断 40 .and() 41 .requestMatchers().antMatchers("/auth/**") // .requestMatchers().antMatchers(...) OAuth2设置对资源的保护如果是用 /**的话 会把上面的也拦截掉 42 .and() 43 .authorizeRequests() 44 .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() { // 重写做权限判断 45 @Override 46 public <O extends FilterSecurityInterceptor> O postProcess(O o) { 47 o.setAccessDecisionManager(accessDecisionManager); // 权限判断 48 return o; 49 } 50 }) 51 .and() 52 .httpBasic(); 53 54 http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); 55 } 56 57 @Override 58 public void configure(ResourceServerSecurityConfigurer resources) throws Exception { 59 resources.authenticationEntryPoint(tokenExceptionEntryPoint); // token失效处理器 60 resources.resourceId("manager"); // 设置资源id 通过client的 resource_ids 来判断是否具有资源权限 资源不存在会报Invalid token does not contain resource id (manager) 61 } 62}

在MySecurityAccessDecisionManager打断点可以发现,全部请求都走这里进行权限判断了,根据认证服务器中的权限组合,匹配uri的请求进行结合方法上的注解权限进行是否有权访问判断,原则是全过则过,否则无权。

SpringSecurityOAuth2(4)根据请求URI动态权限判断(补)下篇文章

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

SpringSecurityOAuth2(9) feign 微服务间调用 token验证

GitHub地址(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fweizongwu%2FSpringCloudOAuth2SpringSecurityFrame.git"项目地址")码云地址(https://gitee.com/wujishu/

SpringSecurityOAuth2(5)自定义登录登出

GitHub地址(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fweizongwu%2FSpringCloudOAuth2SpringSecurityFrame.git"项目地址")码云地址(https://gitee.com/wujishu/

SpringSecurityOAuth2(8) swagger2 集成OAuth2

GitHub地址(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fweizongwu%2FSpringCloudOAuth2SpringSecurityFrame.git"项目地址")码云地址(https://gitee.com/wujishu/