使用 Spring Security OAuth2 进行访问令牌请求的 JWT 不记名交换

Posted

技术标签:

【中文标题】使用 Spring Security OAuth2 进行访问令牌请求的 JWT 不记名交换【英文标题】:JWT bearer exchange for access token request using Spring Security OAuth2 【发布时间】:2016-04-21 07:00:04 【问题描述】:

我的工作设置包括:

授权服务 (AS) 资源服务 (RS) 依赖方 (RP)

实现基于带有 Spring Security (OAuth2) 的 Spring Boot。我有以下工作 2LA 流程:

    RP 能够使用client_secretgrant_type=client_credentials 向AS 发送访问令牌请求。 AS 以访问令牌响应 RP。 RP 能够使用所述访问令牌向 RS 发出授权请求。 RS 能够使用 AS 上的/check_token 端点验证访问令牌。

问题我需要对我的 AS 进行哪些更改,使其在上述第 1 步中接受基于 JWT 的访问令牌请求?

请注意,我不需要基于 JWT 的访问令牌。只有 RP 向 AS 请求访问令牌的初始请求应该是基于 JWT 的请求。

相关问题:How to use Spring OAuth2 JWT Token?

澄清我想知道 code 需要写什么才能使用 Spring Security OAuth2 库从 RP 接受 JWT。 RP的公钥在哪里添加到AS,RP的私钥在哪里添加到OAuth2 rest模板?

RP OAuth2 客户端配置:

@Configuration
@EnableOAuth2Client
open class OAuth2ClientConfiguration 

    val tokenUrl = "http://localhost:8180/oauth/token"

    @Bean
    open fun resource(): OAuth2ProtectedResourceDetails 
        return ClientCredentialsResourceDetails().apply 
            clientId = "demo-rp"
            clientSecret = "rp-secret"
            grantType = "client_credentials"
            scope = listOf("quotes")
            accessTokenUri = tokenUrl
        
    

    @Bean
    open fun restTemplate(): OAuth2RestOperations 
        return OAuth2RestTemplate(
                resource(),
                DefaultOAuth2ClientContext(DefaultAccessTokenRequest()))
    


AS OAuth2 配置:

@Configuration
@EnableAuthorizationServer
open class OAuth2Configuration : AuthorizationServerConfigurerAdapter() 

    @Autowired
    val authenticationManager: AuthenticationManager? = null

    override fun configure(security: AuthorizationServerSecurityConfigurer) 
        // @formatter:off
        security
        .tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')")
        .checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')")
        // @formatter:on
    

    override fun configure(clients: ClientDetailsServiceConfigurer) 
        // @formatter:off
        clients.inMemory()
        .withClient("demo-rp")
            .authorizedGrantTypes("client_credentials")
            .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
            .scopes("quotes")
            .secret("rp-secret")
            .accessTokenValiditySeconds(60)
        .and()
        .withClient("demo-rs")
            .authorizedGrantTypes("client_credentials")
            .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
            .secret("rs-secret")
            .accessTokenValiditySeconds(60)
        // @formatter:on
    

    override fun configure(endpoints: AuthorizationServerEndpointsConfigurer) 
        // @formatter:off
        endpoints
        .authenticationManager(authenticationManager)
        // @formatter:on
    

【问题讨论】:

【参考方案1】:

我最终使用Nimbus OAuth2 SDK 编写了一个客户端,该客户端发送了一个基​​于 JWT 的访问令牌请求。这是 RP 的一部分。

在 AS 中,我添加了一个 JwtTokenEndpointAuthenticationFilter,它检查 ServletRequest 并使用手写的 AuthenticationProvider 执行身份验证。

示例 AS 代码 here。 示例 RP 代码here。

此解决方案的灵感来自here。

【讨论】:

【参考方案2】:

请注意,我不需要基于 JWT 的访问令牌。只有 RP 向 AS 请求访问令牌的初始请求应该是基于 JWT 的请求。

OAuth 2.0 组件在每个流中的交互都是相同的,无论将生成什么类型​​的Access Token。例如,在Password Grant 流中,如果幸运的话,客户端向Authorization Server 发送请求并获得访问令牌。授权服务器使用内存中令牌或 JWT 令牌或持久令牌这一事实并没有改变此特定流程中的交互。

【讨论】:

我不是在谈论流程,而是我需要进行哪些代码更改才能接受来自 RP 的 JWT。我试着让这个问题更清楚一点。

以上是关于使用 Spring Security OAuth2 进行访问令牌请求的 JWT 不记名交换的主要内容,如果未能解决你的问题,请参考以下文章

使用 spring-session 和 spring-cloud-security 时,OAuth2ClientContext (spring-security-oauth2) 不会保留在 Redis

针对授权标头的Spring Security OAuth2 CORS问题

使用spring security jwt spring security oauth2权限控制遇到的坑记录

Spring Security 入门(1-3)Spring Security oauth2.0 指南

Spring Security OAuth2 - 如何使用 OAuth2Authentication 对象?

oauth2 spring-security 如果您在请求令牌或代码之前登录