这篇文章主要讲解了“SpringSecurityOAuth2如何实现根据请求URI动态权限判断”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringSecurityOAuth2如何实现根据请求URI动态权限判断”吧!
一般我们通过@PreAuthorize("hasRole('ROLE_USER')") 注解,以及在HttpSecurity配置权限需求等来控制权限。在这里,我们基于请求的URI来控制访问权限,并且可以使用注解来控制权限访问。
新建一个资源项目,配置资源服务。 首先 自定义一个权限认证MySecurityAccessDecisionManager 继承AccessDecisionManager接口,重写 decide方法, 并且复制默认权限验证AbstractAccessDecisionManager的剩余两个方法(实现注解控制的重点)。用户具有的权限在认证服务器中已经自定义了。
/** * @Description 自定义权限认证,获取url判断是否有权限 * @Author wwz * @Date 2019/08/01 * @Param * @Return */ @Component public class MySecurityAccessDecisionManager implements AccessDecisionManager { private List<AccessDecisionVoter<? extends Object>> decisionVoters; @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { String requestUrl = ((FilterInvocation) object).getRequest().getMethod() + ((FilterInvocation) object).getRequest().getRequestURI(); // System.out.println("requestUrl>>" + requestUrl); // 当前用户所具有的权限 Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); // System.out.println("authorities=" + authorities); for (GrantedAuthority grantedAuthority : authorities) { if (grantedAuthority.getAuthority().equals(requestUrl)) { return; } if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) { return; } } throw new AccessDeniedException("无访问权限"); } /** * 复制默认方法,使得@PreAuthorize("hasRole('ROLE_ADMIN')") 可用 */ @Override public boolean supports(ConfigAttribute attribute) { for (AccessDecisionVoter voter : this.decisionVoters) { if (voter.supports(attribute)) { return true; } } return false; } @Override public boolean supports(Class<?> clazz) { for (AccessDecisionVoter voter : this.decisionVoters) { if (!voter.supports(clazz)) { return false; } } return true; } }
在资源服务配置的httpSecurity中重写并注入:
/** * @Description 资源认证 * @Author wwz * @Date 2019/08/01 * @Param * @Return */ @Configuration @EnableResourceServer @EnableGlobalMethodSecurity(prePostEnabled = true) // 启用注解权限配置 public class MySecurityResourceServerConfig extends ResourceServerConfigurerAdapter { @Autowired private RedisConnectionFactory connectionFactory; @Bean public TokenStore tokenStore() { RedisTokenStore redis = new RedisTokenStore(connectionFactory); return redis; } @Resource private MyAccessDeniedHandler accessDeniedHandler; // 无权访问处理器 @Resource private MyTokenExceptionEntryPoint tokenExceptionEntryPoint; // token失效处理器 @Resource private MySecurityAccessDecisionManager accessDecisionManager; //权限判断 @Override public void configure(HttpSecurity http) throws Exception { http .csrf().disable() .exceptionHandling().authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED)) .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) // 另外,如果不设置,那么在通过浏览器访问被保护的任何资源时,每次是不同的SessionID,并且将每次请求的历史都记录在OAuth3Authentication的details的中 .and() .authorizeRequests().antMatchers("/actuator/health").permitAll().anyRequest().authenticated() // httpSecurity 放过健康检查,其他都需要验证 设置了.anyRequest().authenticated()才回进入自定义的权限判断 .and() .requestMatchers().antMatchers("/auth/**") // .requestMatchers().antMatchers(...) OAuth3设置对资源的保护如果是用 /**的话 会把上面的也拦截掉 .and() .authorizeRequests() .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() { // 重写做权限判断 @Override public <O extends FilterSecurityInterceptor> O postProcess(O o) { o.setAccessDecisionManager(accessDecisionManager); // 权限判断 return o; } }) .and() .httpBasic(); http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.authenticationEntryPoint(tokenExceptionEntryPoint); // token失效处理器 resources.resourceId("manager"); // 设置资源id 通过client的 resource_ids 来判断是否具有资源权限 资源不存在会报Invalid token does not contain resource id (manager) } }
在MySecurityAccessDecisionManager打断点可以发现,全部请求都走这里进行权限判断了,根据认证服务器中的权限组合,匹配uri的请求进行结合方法上的注解权限进行是否有权访问判断,原则是全过则过,否则无权。
感谢各位的阅读,以上就是“SpringSecurityOAuth2如何实现根据请求URI动态权限判断”的内容了,经过本文的学习后,相信大家对SpringSecurityOAuth2如何实现根据请求URI动态权限判断这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。