一、网关鉴权
1.1 引入依赖
< dependency>
< groupId> cn.dev33</ groupId>
< artifactId> sa-token-reactor-spring-boot3-starter</ artifactId>
< version> 1.39.0</ version>
</ dependency>
< dependency>
< groupId> cn.dev33</ groupId>
< artifactId> sa-token-redis-jackson</ artifactId>
< version> 1.39.0</ version>
</ dependency>
< dependency>
< groupId> org.apache.commons</ groupId>
< artifactId> commons-pool2</ artifactId>
</ dependency>
1.2 鉴权接口
package com. ozo. cloud. gateway. core ;
import cn. dev33. satoken. stp. StpInterface ;
import com. ozo. cloud. common. base. context. CurrentUserHolder ;
import com. ozo. cloud. common. base. model. LoginUser ;
import java. util. ArrayList ;
import java. util. List ;
public class SaPermissionImpl implements StpInterface {
@Override
public List < String > getPermissionList ( Object loginId, String loginType) {
LoginUser loginUser = CurrentUserHolder . current ( ) ;
return new ArrayList < > ( loginUser. getMenuPermission ( ) ) ;
}
@Override
public List < String > getRoleList ( Object loginId, String loginType) {
LoginUser loginUser = CurrentUserHolder . current ( ) ;
return new ArrayList < > ( loginUser. getRolePermission ( ) ) ;
}
}
1.3 过滤器配置
package com. ozo. cloud. gateway. config ;
import cn. dev33. satoken. context. SaHolder ;
import cn. dev33. satoken. context. model. SaResponse ;
import cn. dev33. satoken. reactor. filter. SaReactorFilter ;
import cn. dev33. satoken. router. SaHttpMethod ;
import cn. dev33. satoken. router. SaRouter ;
import cn. dev33. satoken. stp. StpInterface ;
import cn. dev33. satoken. stp. StpUtil ;
import cn. hutool. core. collection. CollUtil ;
import cn. hutool. core. util. CharsetUtil ;
import cn. hutool. http. ContentType ;
import cn. hutool. http. Header ;
import cn. hutool. json. JSONUtil ;
import com. ozo. cloud. common. base. model. ResultVO ;
import com. ozo. cloud. gateway. config. properties. SecurityProperties ;
import com. ozo. cloud. gateway. core. SaPermissionImpl ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. boot. context. properties. EnableConfigurationProperties ;
import org. springframework. context. annotation. Bean ;
import org. springframework. context. annotation. Configuration ;
import java. util. List ;
@EnableConfigurationProperties ( SecurityProperties . class )
@Configuration
public class SaTokenConfig {
@Autowired
private SecurityProperties securityProperties;
@Bean
public StpInterface stpInterface ( ) {
return new SaPermissionImpl ( ) ;
}
@Bean
public SaReactorFilter saServletFilter ( ) {
SaReactorFilter saReactorFilter = new SaReactorFilter ( ) ;
saReactorFilter. setBeforeAuth ( obj -> {
SaHolder . getResponse ( )
. setHeader ( "X-XSS-Protection" , "1; mode=block" )
. setHeader ( "X-Content-Type-Options" , "nosniff" )
. setHeader ( "Access-Control-Allow-Origin" , "*" )
. setHeader ( "Access-Control-Allow-Methods" , "POST, GET, OPTIONS, DELETE" )
. setHeader ( "Access-Control-Max-Age" , "3600" )
. setHeader ( "Access-Control-Allow-Headers" , "*" ) ;
SaRouter . match ( SaHttpMethod . OPTIONS )
. free ( r -> {
} )
. back ( ) ;
} )
. setError ( e -> {
SaResponse saResponse = SaHolder . getResponse ( ) ;
saResponse. setHeader ( Header . CONTENT_TYPE . getValue ( ) , ContentType . JSON + ";charset=" + CharsetUtil . UTF_8 ) ;
return JSONUtil . parseObj ( ResultVO . fail ( e. getMessage ( ) ) ) ;
} ) ;
saReactorFilter. addInclude ( "/**" )
. setAuth ( obj -> {
SaRouter . match ( "/**" , r -> StpUtil . checkLogin ( ) ) ;
} ) ;
List < String > excludePathPatterns = securityProperties. getExcludePathPatterns ( ) ;
if ( CollUtil . isNotEmpty ( excludePathPatterns) ) {
saReactorFilter. addExclude ( excludePathPatterns. toArray ( new String [ 0 ] ) ) ;
}
return saReactorFilter;
}
}
1.4 子服务添加Token
package com. ozo. cloud. gateway. filter ;
import cn. dev33. satoken. same. SaSameUtil ;
import org. springframework. cloud. gateway. filter. GatewayFilterChain ;
import org. springframework. cloud. gateway. filter. GlobalFilter ;
import org. springframework. core. Ordered ;
import org. springframework. http. server. reactive. ServerHttpRequest ;
import org. springframework. stereotype. Component ;
import org. springframework. web. server. ServerWebExchange ;
import reactor. core. publisher. Mono ;
@Component
public class ForwardAuthFilter implements GlobalFilter , Ordered {
@Override
public Mono < Void > filter ( ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest newRequest = exchange
. getRequest ( )
. mutate ( )
. header ( SaSameUtil . SAME_TOKEN , SaSameUtil . getToken ( ) )
. build ( ) ;
ServerWebExchange newExchange = exchange. mutate ( ) . request ( newRequest) . build ( ) ;
return chain. filter ( newExchange) ;
}
@Override
public int getOrder ( ) {
return 0 ;
}
}
二、子服务鉴权
2.1 引入依赖
< dependency>
< groupId> cn.dev33</ groupId>
< artifactId> sa-token-spring-boot3-starter</ artifactId>
< version> 1.39.0</ version>
</ dependency>
< dependency>
< groupId> cn.dev33</ groupId>
< artifactId> sa-token-redis-jackson</ artifactId>
< version> 1.39.0</ version>
</ dependency>
< dependency>
< groupId> org.apache.commons</ groupId>
< artifactId> commons-pool2</ artifactId>
</ dependency>
2.2 过滤器配置
package com. ozo. cloud. common. satoken. config ;
import cn. dev33. satoken. context. SaHolder ;
import cn. dev33. satoken. context. model. SaResponse ;
import cn. dev33. satoken. filter. SaServletFilter ;
import cn. dev33. satoken. interceptor. SaInterceptor ;
import cn. dev33. satoken. same. SaSameUtil ;
import cn. hutool. core. util. CharsetUtil ;
import cn. hutool. http. ContentType ;
import cn. hutool. http. Header ;
import cn. hutool. json. JSONUtil ;
import com. ozo. cloud. common. base. model. ResultVO ;
import org. springframework. boot. autoconfigure. AutoConfiguration ;
import org. springframework. boot. autoconfigure. condition. ConditionalOnMissingBean ;
import org. springframework. context. annotation. Bean ;
import org. springframework. security. crypto. bcrypt. BCryptPasswordEncoder ;
import org. springframework. security. crypto. password. PasswordEncoder ;
import org. springframework. web. servlet. config. annotation. InterceptorRegistry ;
import org. springframework. web. servlet. config. annotation. WebMvcConfigurer ;
@AutoConfiguration
public class SaTokenConfig implements WebMvcConfigurer {
@Override
public void addInterceptors ( InterceptorRegistry registry) {
registry. addInterceptor ( new SaInterceptor ( ) )
. addPathPatterns ( "/**" ) ;
}
@Bean
public SaServletFilter getSaServletFilter ( ) {
return new SaServletFilter ( )
. addInclude ( "/**" )
. setAuth ( obj -> {
SaSameUtil . checkCurrentRequestToken ( ) ;
} )
. setError ( e -> {
SaResponse saResponse = SaHolder . getResponse ( ) ;
saResponse. setHeader ( Header . CONTENT_TYPE . getValue ( ) , ContentType . JSON + ";charset=" + CharsetUtil . UTF_8 ) ;
return JSONUtil . parseObj ( ResultVO . fail ( e. getMessage ( ) ) ) ;
} ) ;
}
@Bean
@ConditionalOnMissingBean
public PasswordEncoder passwordEncoder ( ) {
return new BCryptPasswordEncoder ( ) ;
}
}
2.3 拦截器
package com. ozo. cloud. common. satoken. interceptor ;
import cn. dev33. satoken. same. SaSameUtil ;
import feign. RequestInterceptor ;
import feign. RequestTemplate ;
public class FeignInterceptor implements RequestInterceptor {
@Override
public void apply ( RequestTemplate requestTemplate) {
requestTemplate. header ( SaSameUtil . SAME_TOKEN , SaSameUtil . getToken ( ) ) ;
}
}
2.4 接口使用拦截器
package com. ozo. cloud. api. auth. feign ;
import com. ozo. cloud. common. base. model. ResultVO ;
import com. ozo. cloud. common. satoken. interceptor. FeignInterceptor ;
import org. springframework. cloud. openfeign. FeignClient ;
import org. springframework. web. bind. annotation. GetMapping ;
@FeignClient ( name = "ozo-cloud-auth" , path = "/auth" , configuration = FeignInterceptor . class )
public interface AuthFeignClient {
@GetMapping ( "/userInfo" )
ResultVO < Object > getUserInfo ( ) ;
}