您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“如何配置統(tǒng)一資源服務(wù)器模塊”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“如何配置統(tǒng)一資源服務(wù)器模塊”吧!
首先我們需要改造認(rèn)證服務(wù)器,需要認(rèn)證服務(wù)器在構(gòu)建用戶權(quán)限的時(shí)候使用的是權(quán)限標(biāo)識字段。對于代碼而言只需要 UserDetailServiceImpl#loadUserByUsername()
中修改即可。
@Overridepublic UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { //獲取本地用戶 SysUser sysUser = sysUserMapper.selectByUserName(userName); if(sysUser != null){ //獲取當(dāng)前用戶的所有角色 List<SysRole> roleList = sysRoleService.listRolesByUserId(sysUser.getId()); sysUser.setRoles(roleList.stream().map(SysRole::getRoleCode).collect(Collectors.toList())); List<Integer> roleIds = roleList.stream().map(SysRole::getId).collect(Collectors.toList()); //獲取所有角色的權(quán)限 List<SysPermission> permissionList = sysPermissionService.listPermissionsByRoles(roleIds); //基于方法攔截.只需放入用戶權(quán)限標(biāo)識即可 List<String> permissionMethodList = permissionList.stream() .map(SysPermission::getPermission) .collect(Collectors.toList()); sysUser.setPermissions(permissionMethodList); //構(gòu)建oauth3的用戶 return buildUserDetails(sysUser); }else{ throw new UsernameNotFoundException("用戶["+userName+"]不存在"); } }
網(wǎng)關(guān)服務(wù)器不再需要進(jìn)行用戶權(quán)限校驗(yàn),所以我們需要將相關(guān)校驗(yàn)邏輯全部刪除。
@Configurationpublic class SecurityConfig { @Bean SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception{ http .httpBasic().disable() .csrf().disable(); return http.build(); } }
完成了上面兩步后就到了最重要的步驟了,需要建立一個(gè)獨(dú)立的資源服務(wù)器配置模塊,用于其他模塊引用。
首先我們得建立一個(gè)單獨(dú)的資源服務(wù)模塊 cloud-component-security-starter
,如下為改造后的代碼結(jié)構(gòu)圖。
然后,要讓一個(gè)普通后端服務(wù)成為資源服務(wù)器,需要有一個(gè)配置類繼承 ResourceServerConfigurerAdapter
并進(jìn)行相關(guān)配置,那在我們獨(dú)立的資源服務(wù)器模塊我們首先得創(chuàng)建一個(gè)這樣的配置類,這個(gè)比較簡單,只需從之前的模塊中拷貝一份出來。
public class CloudResourceServerConfigure extends ResourceServerConfigurerAdapter { private CustomAccessDeniedHandler accessDeniedHandler; private CustomAuthenticationEntryPoint exceptionEntryPoint; private TokenStore tokenStore; @Value("${security.oauth3.resource.id}") private String resourceId ; @Autowired(required = false) public void setAccessDeniedHandler(CustomAccessDeniedHandler accessDeniedHandler) { this.accessDeniedHandler = accessDeniedHandler; } @Autowired(required = false) public void setExceptionEntryPoint(CustomAuthenticationEntryPoint exceptionEntryPoint) { this.exceptionEntryPoint = exceptionEntryPoint; } @Autowired(required = false) public void setTokenStore(TokenStore tokenStore) { this.tokenStore = tokenStore; } @Override public void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll() .antMatchers( "/v2/api-docs/**", "/swagger-resources/**", "/swagger-ui.html", "/webjars/**" ).permitAll() .anyRequest().authenticated() .and() .csrf().disable(); } @Override public void configure(ResourceServerSecurityConfigurer resources) { DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter(); UserAuthenticationConverter userTokenConverter = new CustomUserAuthenticationConverter(); accessTokenConverter.setUserTokenConverter(userTokenConverter); if (exceptionEntryPoint != null) { resources.authenticationEntryPoint(exceptionEntryPoint); } if (accessDeniedHandler != null) { resources.accessDeniedHandler(accessDeniedHandler); } resources.resourceId(resourceId).tokenStore(tokenStore); } }
現(xiàn)在有了資源服務(wù)器配置,那其他模塊如何引入這個(gè)配置類呢?
這里我們可以借助SpringBoot的Enable模塊驅(qū)動能力,通過@EnableXXX注解導(dǎo)入配置類。
我們創(chuàng)建一個(gè)自定義注解類 EnableCloudResourceServer
,其他模塊通過 @EnableCloudResourceServer
注解即可導(dǎo)入資源服務(wù)器配置
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@EnableResourceServer //開啟資源服務(wù)器@Import({CloudResourceServerConfigure.class, TokenStoreConfigure.class})public @interface EnableCloudResourceServer { }
最后我們知道微服務(wù)授權(quán)是基于方法攔截,基于方法攔截我們就需要開啟 @EnableGlobalMethodSecurity
,并且需要將我們自定義的權(quán)限注解功能遷移過來。所以我們再創(chuàng)建一個(gè)配置類用于配置上述功能。
@EnableGlobalMethodSecurity(prePostEnabled = true) public class CloudSecurityAutoConfigure extends GlobalMethodSecurityConfiguration { @Bean @ConditionalOnMissingBean(name = "accessDeniedHandler") public CustomAccessDeniedHandler accessDeniedHandler() { return new CustomAccessDeniedHandler(); } @Bean @ConditionalOnMissingBean(name = "authenticationEntryPoint") public CustomAuthenticationEntryPoint authenticationEntryPoint() { return new CustomAuthenticationEntryPoint(); } @Override protected MethodSecurityExpressionHandler createExpressionHandler() { return new CustomMethodSecurityExpressionHandler(); } }
經(jīng)過上面的改造,一個(gè)獨(dú)立的資源服務(wù)器創(chuàng)建成功了,現(xiàn)在剩下的就是對微服務(wù)的改造。
在maven中刪除原oauth3.0的相關(guān)配置,引入自定義 cloud-component-security-starter
<dependency> <groupId>com.jianzh6.cloud</groupId> <artifactId>cloud-component-security-starter</artifactId></dependency>
刪除所有資源服務(wù)器相關(guān)代碼(此過程略)
修改主啟動類,通過 @EnableCloudResourceServer
引入資源服務(wù)器配置
@EnableDiscoveryClient@SpringCloudApplication@EnableCloudResourceServerpublic class AccountServiceApplication { public static void main(String[] args) { SpringApplication.run(AccountServiceApplication.class, args); } }
在需要攔截的Controller方法中添加自定義權(quán)限攔截注解 @PreAuthorize("hasPrivilege('queryAccount')")
當(dāng)然也可以使用SpringSecurity原生注解 @PreAuthorize("hasAuthority('queryAccount')")
,兩者作用一樣。
@GetMapping("/account/getByCode/{accountCode}")@PreAuthorize("hasPrivilege('queryAccount')")//@PreAuthorize("hasAuthority('queryAccount')")public ResultData<AccountDTO> getByCode(@PathVariable(value = "accountCode") String accountCode){ AccountDTO accountDTO = accountService.selectByCode(accountCode); return ResultData.success(accountDTO); }
我們訪問一個(gè)沒有權(quán)限的方法會出現(xiàn)如下錯(cuò)誤提示,表明獨(dú)立資源服務(wù)器成功配置
{ "status": 500, "message": "不允許訪問", "data": null, "success": false, "timestamp": 1619052359563}
提示:@PreAuthorize 注解的異常,拋出AccessDeniedException異常,不會被accessDeniedHandler捕獲,而是會被全局異常捕獲。如果需要自定義
@PreAuthorize
錯(cuò)誤異常,可以通過全局的@RestControllerAdvice
進(jìn)行異常攔截
攔截后的自定義異常如下:
{ "status": 2003, "message": "沒有權(quán)限訪問該資源", "data": null, "success": false, "timestamp": 1619052359563}
到此,相信大家對“如何配置統(tǒng)一資源服務(wù)器模塊”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。