Jwt 如何使用Oauth2使API网关成为无状态的身份验证/授权过程?

Jwt 如何使用Oauth2使API网关成为无状态的身份验证/授权过程?,jwt,spring-cloud,spring-webflux,spring-oauth2,spring-cloud-gateway,Jwt,Spring Cloud,Spring Webflux,Spring Oauth2,Spring Cloud Gateway,在我的设计中,我有一个API网关(SpringCloudAPI网关)、授权服务器(Oauth2)和资源服务器(microservice)。(我也有一个CAS服务器,但为了简单起见,现在可以忽略它) 我只想使用API网关重定向客户端请求 如果用户未通过身份验证,则应将请求发送给授权部门 服务器和身份验证和授权过程结束后 完成后,授权服务器应在中返回JSESSION和JWT 访问令牌头。之后,API网关应返回JSESSION 和JWT给客户 如果用户经过身份验证,则应将请求发送到资源服务器 所以

在我的设计中,我有一个API网关(SpringCloudAPI网关)、授权服务器(Oauth2)和资源服务器(microservice)。(我也有一个CAS服务器,但为了简单起见,现在可以忽略它)

我只想使用API网关重定向客户端请求

  • 如果用户未通过身份验证,则应将请求发送给授权部门 服务器和身份验证和授权过程结束后 完成后,授权服务器应在中返回JSESSION和JWT 访问令牌头。之后,API网关应返回JSESSION 和JWT给客户
  • 如果用户经过身份验证,则应将请求发送到资源服务器
所以API网关将是无状态的,只用于重定向请求。但当我成功登录时,会设置JSESSION和会话cookie,并且不会将JWT发送到客户端。(据日志了解,API网关具有JWT,但不是简单地将其发送到客户端,而是使用会话密钥和发送会话密钥存储它)

如何使API网关成为无状态,并将access\u令牌头中的JWT发送到客户端?

这是我的密码:

授权服务器:

@EnableWebSecurity
@Order(1)
public class MySecurityConfigurationDev extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/login/**", "/oauth/**", "/userinfo")
                .permitAll()
                .and()
                .formLogin().permitAll().and()
                .authorizeRequests().anyRequest().authenticated();
        http.csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("{noop}pass").roles("ADMIN");
    }
}
@EnableWebFluxSecurity
public class MySecurityConfiguration {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http, ReactiveClientRegistrationRepository clientRegistrationRepository) {
        http.authorizeExchange().anyExchange().authenticated().and().oauth2Login();
        return http.build();
    }
}

API网关:

@EnableWebSecurity
@Order(1)
public class MySecurityConfigurationDev extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/login/**", "/oauth/**", "/userinfo")
                .permitAll()
                .and()
                .formLogin().permitAll().and()
                .authorizeRequests().anyRequest().authenticated();
        http.csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("{noop}pass").roles("ADMIN");
    }
}
@EnableWebFluxSecurity
public class MySecurityConfiguration {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http, ReactiveClientRegistrationRepository clientRegistrationRepository) {
        http.authorizeExchange().anyExchange().authenticated().and().oauth2Login();
        return http.build();
    }
}

日志记录:
级别:
根:跟踪
org.springframework.cloud.gateway:调试
reactor.netty.http.client:调试
com.netflix.DiscoveryClient:错误
org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator:错误
com.netflix.discovery.shared.resolver.aws.ConfigClusterResolver:错误
服务器:
港口:8085
尤里卡:
客户:
服务URL:
默认区域:http://localhost:8010/eureka
春天:
应用程序:
名称:网关服务器
云:
网关:
默认过滤器:
-RemoveRequestHeader=Cookie
-令牌中继=
路线:
-id:用户路径
谓词:
-路径=/网关用户/**
过滤器:
-重写路径=/gateway user/(?*),/user/$\{segment}
-RemoveRequestHeader=Cookie
-姓名:Hystrix
args:
名称:fallback命令
fallbackUri:forward:/fallback/错误
uri:“lb://USER-RESOURCE-SERVER”
-id:地址和路线
谓词:
-路径=/网关地址/**
过滤器:
-重写路径=/gateway address/(?*),/address/$\{segment}
uri:“lb://ADDRESS-RESOURCE-SERVER”
安全:
oauth2:
客户:
注册:
登录客户端:
供应商:uaa
客户端id:第一个客户端
客户秘密:NoonewillerGuess
授权授予类型:授权\ U代码
重定向uri:“{baseUrl}/login/oauth2/code/{registrationId}”
经营范围:定制
供应商:
阿拉伯联合酋长国:
授权uri:http://localhost:8094/oauth/authorize
令牌uri:http://localhost:8094/oauth/token
用户信息uri:http://localhost:8094/userinfo
用户名属性:用户名
用户信息验证方法:表单

**两台服务器的Spring Boot版本都是2.1.6版本。

网关本身是无状态的。“一定是你们正在做的事情引入了状态。”斯宾塞·吉布,嘿,谢谢回应。我完全实现了这个blog()和代码(),没有任何更改。但它似乎是有状态的。jwt仍然存储为会话。我想是虫子。如果不是,你能提供一些演示吗?谢谢,我不能说关于jwt的任何事情,因为这不是来自gateway@spencergibb,我想OP指的是
websessionserveroauth2authorizedclientpository
,它通过将身份验证与HttpSession链接起来,使网关具有状态。