Spring boot 如何在不使用jwt的情况下实现资源服务器 总结

Spring boot 如何在不使用jwt的情况下实现资源服务器 总结,spring-boot,spring-security-oauth2,Spring Boot,Spring Security Oauth2,我想知道如果我使用webflux和oauth2而不使用jwt,我想在redis中存储令牌,如何配置资源服务器 实际行为 首先,我检索了由DefaultTokenServices和RedistokeStore创建的令牌,当它被创建时,它被存储在redis中。返回值类似于以下json: { "access_token": "0d0dd242-cbdf-4e47-842b-c6ad5edae332", "token_type": "bearer", "refresh_token

我想知道如果我使用webflux和oauth2而不使用jwt,我想在redis中存储令牌,如何配置资源服务器

实际行为 首先,我检索了由
DefaultTokenServices
RedistokeStore
创建的令牌,当它被创建时,它被存储在redis中。返回值类似于以下json:

{
    "access_token": "0d0dd242-cbdf-4e47-842b-c6ad5edae332",
    "token_type": "bearer",
    "refresh_token": "2189ff33-eb96-49d1-ab60-6ad337ae06a9",
    "expires_in": 7199,
    "scope": "read write"
}
然后我尝试访问受保护的资源
localhost:3660/api/auth/user
,以检索当前用户信息,并添加一个标题,如
Authorization:Bearer 0d0dd242-cbdf-4e47-842b-c6ad5edae332

然后我得到了401

预期行为 我想访问受保护的资源
/api/auth/user
,但我不能。我已经寻找了很多解决方案,但我仍然没有想到这一点

代码 这是我的
WebSecurityConfig
,我使用Webflux模块,而不是Web模块

@配置
@启用WebFluxSecurity
公共类WebSecurity配置{
@豆子
公共密码编码器PasswordEncoder(){
返回新的BCryptPasswordEncoder();
}
@豆子
SecurityWebFilterChain SecurityWebFilterChain(ServerHttpSecurity http,ReactiveAuthenticationManager ReactiveAuthenticationManager){
http.authorizeExchange(
exchange->exchange.pathMatchers(HttpMethod.OPTIONS).permitAll()
.pathMatchers(“/api/auth/signup/**”和“/api/auth/password”).permitAll()
.pathMatchers(“/api/auth/login”,“/api/auth/admin/login”).permitAll()
.pathMatchers(HttpMethod.POST,“/api/auth/setting/mfa”).hasAuthority(Role.mfa.getAuthority())
.pathMatchers(“/api/auth/setting/sms”).hasAnyAuthority(Role.sms.getAuthority(),Role.USER.getAuthority())
.anyExchange().hasAnyAuthority(Role.USER.getAuthority()、Role.ADMIN.getAuthority()、Role.ROOT.getAuthority())
);
返回http
.authenticationManager(反应式authenticationManager)
//.oauth2ResourceServer(oauth2ResourceServer规范->oauth2ResourceServer规范)
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.build();
}
@豆子
@ConditionalOnMissingBean(ReactiveAuthenticationManager.class)
ReactiveAuthenticationManager ReactiveAuthenticationManager(默认令牌服务令牌服务、,
重新连接(重新连接){
返回新的MscpAuthenticationManager(令牌服务、重新连接);
}
}
另一种配置:

@Slf4j
@配置
@启用JPA审核
@使能调度
公共类MscpAuthorizationConfig{
私有最终再连接工厂连接工厂;
私有最终客户端详细信息服务客户端详细信息服务;
公共MscpAuthorizationConfig(重新连接工厂连接工厂,
客户端详细信息服务客户端详细信息服务){
this.connectionFactory=连接工厂;
this.clientDetailsService=clientDetailsService;
}
@豆子
公共令牌库令牌库(){
返回新的RedistokeStore(connectionFactory);
}
@豆子
RouterFunction路由(AuthenticationHandler AuthenticationHandler){
返回路线()
.path(“/api/auth”,api->api
.path(“/”,authenticationHandler::routes)
)
.build();
}
@豆子
公共DefaultTokenServices令牌服务(){
DefaultTokenServices tokenServices=新的DefaultTokenServices();
setTokenStore(tokenStore());
tokenServices.setSupportRefreshToken(true);
setClientDetailsService(clientDetailsService);
退货服务;
}
@豆子
公共重新连接重新连接(){
返回connectionFactory.getConnection();
}
}
AuthenticationHandler:

@组件
@Slf4j
公共类AuthenticationHandler{
私有最终身份验证服务AuthenticationService;
公共AuthenticationHandler(AuthenticationService AuthenticationService){
this.authenticationService=authenticationService;
}
公共路由功能路由(){
返回路线()
.POST(“/login”,request->request.bodyToMono(login.class)
.switchIfEmpty(Mono.error(新的ApplicationException(APIRERRORS.SYSTEM_错误,“请求参数不能为null”))
.publishOn(Schedulers.elastic())
.doOnNext(System.out::println)
.map(authenticationService::authenticate)
.flatMap(oAuth2AccessToken->{
String format=String.format(“%s%s”,OAuth2AccessToken.BEARER_类型,OAuth2AccessToken.getValue());
log.info(“令牌类型为[{}]”,oAuth2AccessToken.getTokenType());
log.info(“过期日期为[{}]”,oAuth2AccessToken.getExpiration();
返回ok()
.header(HttpHeaders.AUTHORIZATION,格式)
.header(HttpHeaders.CONTENT_类型,“application/json;charset=UTF-8”)
.header(HttpHeaders.CACHE_控件,“无存储”)
.header(HttpHeaders.PRAGMA,“无缓存”)
.bodyValue(oAuth2AccessToken);
})
)
.GET(“/user”,request->ok().bodyValue(request.principal()))
.build();
}
}
这是application.yml:

服务器:
港口:3660
春天:
应用程序:
名称:AuthAPI
redis:
主持人:192.168.10.113
生菜:
游泳池:
最大等待时间:3000毫秒
最大怠速:15
最大有效时间:15
最小怠速:3
数据源:
plugins {
    id 'org.springframework.boot' version '2.2.5.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}

group = 'com.keanu.mscp'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = '11'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
    mavenLocal()
}

ext {
    set('springCloudVersion', "Hoxton.SR3")
}

dependencies {
    implementation 'com.keanu.mscp:java-infra:1.0.0-SNAPSHOT'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    implementation 'org.apache.commons:commons-pool2'
//    implementation 'org.springframework.cloud:spring-cloud-starter-oauth2'
    implementation 'org.springframework.security.oauth:spring-security-oauth2:2.3.8.RELEASE'
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'mysql:mysql-connector-java'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

test {
    useJUnitPlatform()
}