您好,登錄后才能下訂單哦!
這篇文章主要講解了“SpringSecurityOAuth2如何實現(xiàn)根據(jù)請求URI動態(tài)權(quán)限判斷”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“SpringSecurityOAuth2如何實現(xiàn)根據(jù)請求URI動態(tài)權(quán)限判斷”吧!
一般我們通過@PreAuthorize("hasRole('ROLE_USER')") 注解,以及在HttpSecurity配置權(quán)限需求等來控制權(quán)限。在這里,我們基于請求的URI來控制訪問權(quán)限,并且可以使用注解來控制權(quán)限訪問。
新建一個資源項目,配置資源服務(wù)。 首先 自定義一個權(quán)限認(rèn)證MySecurityAccessDecisionManager 繼承AccessDecisionManager接口,重寫 decide方法, 并且復(fù)制默認(rèn)權(quán)限驗證AbstractAccessDecisionManager的剩余兩個方法(實現(xiàn)注解控制的重點)。用戶具有的權(quán)限在認(rèn)證服務(wù)器中已經(jīng)自定義了。
/** * @Description 自定義權(quán)限認(rèn)證,獲取url判斷是否有權(quán)限 * @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); // 當(dāng)前用戶所具有的權(quán)限 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("無訪問權(quán)限"); } /** * 復(fù)制默認(rèn)方法,使得@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; } }
在資源服務(wù)配置的httpSecurity中重寫并注入:
/** * @Description 資源認(rèn)證 * @Author wwz * @Date 2019/08/01 * @Param * @Return */ @Configuration @EnableResourceServer @EnableGlobalMethodSecurity(prePostEnabled = true) // 啟用注解權(quán)限配置 public class MySecurityResourceServerConfig extends ResourceServerConfigurerAdapter { @Autowired private RedisConnectionFactory connectionFactory; @Bean public TokenStore tokenStore() { RedisTokenStore redis = new RedisTokenStore(connectionFactory); return redis; } @Resource private MyAccessDeniedHandler accessDeniedHandler; // 無權(quán)訪問處理器 @Resource private MyTokenExceptionEntryPoint tokenExceptionEntryPoint; // token失效處理器 @Resource private MySecurityAccessDecisionManager accessDecisionManager; //權(quán)限判斷 @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) // 另外,如果不設(shè)置,那么在通過瀏覽器訪問被保護的任何資源時,每次是不同的SessionID,并且將每次請求的歷史都記錄在OAuth3Authentication的details的中 .and() .authorizeRequests().antMatchers("/actuator/health").permitAll().anyRequest().authenticated() // httpSecurity 放過健康檢查,其他都需要驗證 設(shè)置了.anyRequest().authenticated()才回進入自定義的權(quán)限判斷 .and() .requestMatchers().antMatchers("/auth/**") // .requestMatchers().antMatchers(...) OAuth3設(shè)置對資源的保護如果是用 /**的話 會把上面的也攔截掉 .and() .authorizeRequests() .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() { // 重寫做權(quán)限判斷 @Override public <O extends FilterSecurityInterceptor> O postProcess(O o) { o.setAccessDecisionManager(accessDecisionManager); // 權(quán)限判斷 return o; } }) .and() .httpBasic(); http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.authenticationEntryPoint(tokenExceptionEntryPoint); // token失效處理器 resources.resourceId("manager"); // 設(shè)置資源id 通過client的 resource_ids 來判斷是否具有資源權(quán)限 資源不存在會報Invalid token does not contain resource id (manager) } }
在MySecurityAccessDecisionManager打斷點可以發(fā)現(xiàn),全部請求都走這里進行權(quán)限判斷了,根據(jù)認(rèn)證服務(wù)器中的權(quán)限組合,匹配uri的請求進行結(jié)合方法上的注解權(quán)限進行是否有權(quán)訪問判斷,原則是全過則過,否則無權(quán)。
感謝各位的閱讀,以上就是“SpringSecurityOAuth2如何實現(xiàn)根據(jù)請求URI動態(tài)權(quán)限判斷”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對SpringSecurityOAuth2如何實現(xiàn)根據(jù)請求URI動態(tài)權(quán)限判斷這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。