当前位置: 首页 > 知识库问答 >
问题:

调用spring授权服务器OAuth2 RESTendpoint

常小白
2023-03-14

尝试使用 Spring 授权服务器实现 OAuth2 协议。使用以下配置创建了一个简单的应用程序。

@SpringBootApplication
class AuthorizationServerApplication

fun main(args: Array<String>) {
    runApplication<AuthorizationServerApplication>(*args)
}
@Configuration
@Import(OAuth2AuthorizationServerConfiguration::class)
class AuthorizationServerConfig {

    @Bean
    fun registeredClientRepository(): RegisteredClientRepository? {
        val registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("client")
            .clientSecret("{noop}client-secret")
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .authorizationGrantType(AuthorizationGrantType.PASSWORD)
            .redirectUri("http://example-host:9002/test/admin")
            .redirectUri("http://example-host:9002/test")
            .scope(OidcScopes.OPENID)
            .scope("read")
            .build()
        return InMemoryRegisteredClientRepository(registeredClient)
    }

    ...

    @Bean
    fun providerSettings(): ProviderSettings? {
        return ProviderSettings.builder()
            .issuer("http://example-host:9000")
            .build()
    }
}
@EnableWebSecurity
class DefaultSecurityConfig {

    @Bean
    fun defaultSecurityFilterChain(http: HttpSecurity): SecurityFilterChain? {
        http
            .authorizeRequests { authorizeRequests ->
                authorizeRequests
                    .anyRequest().permitAll()
            }
            // these are disabled so that I won't get any additional issue this needs to be changed
            .formLogin().disable()
            .csrf().disable()

        return http.build()
    }

    @Bean
    fun users(): UserDetailsService? {
        val admin: UserDetails = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("password")
            .roles("ADMIN")
            .authorities("read", "write")
            .build()

        val user: UserDetails = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .authorities("read")
            .build()
        return InMemoryUserDetailsManager(admin, user)
    }
}

调用以下endpoint时:获取 http://example-host:9000/.well-known/oauth-authorization-server 我得到这些:

{
    "issuer": "http://example-host:9000",
    "authorization_endpoint": "http://example-host:9000/oauth2/authorize",
    "token_endpoint": "http://example-host:9000/oauth2/token",
    "token_endpoint_auth_methods_supported": [
        "client_secret_basic",
        "client_secret_post",
        "client_secret_jwt",
        "private_key_jwt"
    ],
    "jwks_uri": "http://example-host:9000/oauth2/jwks",
    "response_types_supported": [
        "code"
    ],
    "grant_types_supported": [
        "authorization_code",
        "client_credentials",
        "refresh_token"
    ],
    "revocation_endpoint": "http://example-host:9000/oauth2/revoke",
    "revocation_endpoint_auth_methods_supported": [
        "client_secret_basic",
        "client_secret_post",
        "client_secret_jwt",
        "private_key_jwt"
    ],
    "introspection_endpoint": "http://example-host:9000/oauth2/introspect",
    "introspection_endpoint_auth_methods_supported": [
        "client_secret_basic",
        "client_secret_post",
        "client_secret_jwt",
        "private_key_jwt"
    ],
    "code_challenge_methods_supported": [
        "S256"
    ]
}

我正在尝试通过身份验证并尝试遵循此文档。我尝试了多个电话,其中之一是:

curl --location --request POST 'example-host:9000/oauth2/token' \
--header 'Authorization: Basic YWRtaW46cGFzc3dvcmQ=' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=client' \
--data-urlencode 'client_secret=client-secret'

我大部分时间都是带着不同的信息返回401。我真的想不出在哪里可以找到一些带有示例的文档,因为我能够找到的示例对我的用例没有什么帮助。我不完全理解如果客户端是前端应用程序,我将如何验证和使用资源服务器的endpoint。也许我误解了什么?

编辑:请求令牌endpoint时从授权服务器添加跟踪日志:

curl --location --request POST 'example-host:9000/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=client' \
--data-urlencode 'client_secret=client-secret' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=user' \
--data-urlencode 'password=password'
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer$$Lambda$746/0x000000080105b608@7a764446, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@841f2ce, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@38eb32b, org.springframework.security.web.context.SecurityContextPersistenceFilter@4232bd1e, org.springframework.security.oauth2.server.authorization.web.ProviderContextFilter@1c463b0b, org.springframework.security.web.header.HeaderWriterFilter@6e87e57e, org.springframework.security.web.csrf.CsrfFilter@3657ca3e, org.springframework.security.web.authentication.logout.LogoutFilter@36c9161d, org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationEndpointFilter@c85053, org.springframework.security.oauth2.server.authorization.oidc.web.OidcProviderConfigurationEndpointFilter@827dabb, org.springframework.security.oauth2.server.authorization.web.NimbusJwkSetEndpointFilter@3fce33c2, org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationServerMetadataEndpointFilter@5f5e39a5, org.springframework.security.oauth2.server.authorization.web.OAuth2ClientAuthenticationFilter@6f53bec6, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@1be28be5, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@12322dee, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@4aba4a37, org.springframework.security.web.session.SessionManagementFilter@3c29c1e5, org.springframework.security.web.access.ExceptionTranslationFilter@5e60456e, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@5771f1b4, org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter@1ec08e27, org.springframework.security.oauth2.server.authorization.web.OAuth2TokenIntrospectionEndpointFilter@548d0a8d, org.springframework.security.oauth2.server.authorization.web.OAuth2TokenRevocationEndpointFilter@6c15398a, org.springframework.security.oauth2.server.authorization.oidc.web.OidcUserInfoEndpointFilter@6bcb4915]] (1/2)
2022-06-14 16:41:47.154 DEBUG 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Securing POST /oauth2/token
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking DisableEncodeUrlFilter (1/22)
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking WebAsyncManagerIntegrationFilter (2/22)
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking SecurityContextPersistenceFilter (3/22)
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] w.c.HttpSessionSecurityContextRepository : Created SecurityContextImpl [Null authentication]
2022-06-14 16:41:47.154 DEBUG 34744 --- [nio-9000-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking ProviderContextFilter (4/22)
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking HeaderWriterFilter (5/22)
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking CsrfFilter (6/22)
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.csrf.CsrfFilter         : Did not protect against CSRF since request did not match And [CsrfNotRequired [TRACE, HEAD, GET, OPTIONS], Not [Or [org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer$$Lambda$746/0x000000080105b608@7a764446]]]
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking LogoutFilter (7/22)
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.s.w.a.logout.LogoutFilter            : Did not match request to Ant [pattern='/logout', POST]
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking OAuth2AuthorizationEndpointFilter (8/22)
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking OidcProviderConfigurationEndpointFilter (9/22)
2022-06-14 16:41:47.154 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking NimbusJwkSetEndpointFilter (10/22)
2022-06-14 16:41:47.155 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking OAuth2AuthorizationServerMetadataEndpointFilter (11/22)
2022-06-14 16:41:47.155 TRACE 34744 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy        : Invoking OAuth2ClientAuthenticationFilter (12/22)
2022-06-14 16:41:47.155 TRACE 34744 --- [nio-9000-exec-2] o.s.s.authentication.ProviderManager     : Authenticating request with JwtClientAssertionAuthenticationProvider (1/11)
2022-06-14 16:41:47.155 TRACE 34744 --- [nio-9000-exec-2] o.s.s.authentication.ProviderManager     : Authenticating request with ClientSecretAuthenticationProvider (2/11)
2022-06-14 16:41:47.155 TRACE 34744 --- [nio-9000-exec-2] o.s.s.authentication.ProviderManager     : Authenticating request with PublicClientAuthenticationProvider (3/11)
2022-06-14 16:41:47.155 TRACE 34744 --- [nio-9000-exec-2] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match request to [Is Secure]
2022-06-14 16:41:47.155 DEBUG 34744 --- [nio-9000-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-06-14 16:41:47.156 DEBUG 34744 --- [nio-9000-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-06-14 16:41:47.156 DEBUG 34744 --- [nio-9000-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request

共有2个答案

赖渊
2023-03-14

客户端 ID 和客户端密钥必须采用 Base64 格式。

String hashed_keys = Base64.encode("client_id:client_secret");

并且必须将其作为http头传递

curl -L -X POST 'http://example-host:9000/oauth2/token' -H "Authorisation: hashed_keys" -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=client_credentials'
岑光熙
2023-03-14

首先,在您的情况下,您不需要令牌请求中的Authorization头,因为您明确允许所有请求通过authorizeRequests.anyRequest().permitAll()

其次,在<code>curl</code>请求中,您至少没有指定所需的授权类型及其参数。

例如,对于passwordgrant类型,请求可能如下所示:

curl -L -X POST 'example-host:9000/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=client' \
--data-urlencode 'client_secret=client-secret' \ 
--data-urlencode 'grant_type=password' \ 
--data-urlencode 'username=user' \ 
--data-urlencode 'password=password'

更新:

>

  • Spring授权服务器0.3.0不支持passwordgrant类型,正如它在 部分中显示的那样。众所周知的/oauth授权服务器 endpoint输出。org.springframework.security.oauth2.server.authorization中没有这样的身份验证提供者。身份验证包。

    要使至少client_credentials令牌请求有效,请添加

    .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
    

    (如果您想在文章正文中传递< code>client_id和< code>client_secret)

    .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
    

    到您的< code>RegisteredClient资料库中的< code>RegisteredClient。那么这可以用

    curl -L -X POST 'http://example-host:9000/oauth2/token' -H 'Content-Type: application/x-www-form-urlencoded' -d 'grant_type=client_credentials&client_id=client&client_secret=client-secret'
    

    (请务必通过注册客户的实际client_idclient_secret

    此外,如果您导入OAuth2AuthorizationServerConfigation,则会创建用于身份验证服务器endpoint的默认SecurityFilterchain,并且无需手动定义它。另一方面,您的应用程序身份验证可能仍然需要SecurityFilterchain

  •  类似资料:
    • 我在下面设置Spring配置: 和Maven设置如下:

    • 我试图在spring cloud gateway(spring-cloud-gateway 2.0.0.M5)后面运行一个oauth2授权服务器(spring-security-oauth2 2.2.1.Release),这两个服务器都带有spring boot 2.0.0.RC1。如果我直接调用授权服务器,它可以正常工作,但如果我通过网关(使用curl或浏览器)调用它,调用将保持不变,没有应答。

    • 我想用Spring授权服务器项目构建一个授权服务器。现在我想使用AuthorizationGrantType.PASSWORD. 我从Spring授权服务器项目的示例中开发了一个演示项目。但是,当我尝试使用http://localhost:9000/oauth2/token?grant_type=password获取令牌时 我在这里错过了什么? 依赖项:spring boot starter we

    • 我有两个Spring启动应用程序。后端部分-可以访问数据库,它用作Rest API和管理面板。前端部分-使用Rest API为客户端显示信息。 因此,我对客户端(前端)的配置安全性有问题,对管理面板也有问题,授权是通过会话实现的。以前,客户端部分的授权是通过JWT令牌实现的,但我不太明白如何为每个客户端存储令牌,并在向Rest API发送请求时使用它。 这是我的安全配置: 那么,可以使用JWT令牌

    • 我需要了解在我的项目范围内使用autheorizaion服务器的便利性。 我们正在实现我们的服务并将其部署到客户环境中。 客户基础结构已经提供了一种身份验证机制,以便对用户进行身份验证。 此机制拦截所有通信并将用户重定向到“登录”表单。 之后,用户被重定向到我们的服务,我们必须处理和消化它,并使用JWT令牌进行响应。 这是我感到迷茫的地方: 我在想: 使用Spring oauth2 向授权服务器请

    • 我有一个使用SpringCloud配置的Spring Boot应用程序,我正在尝试从Bitbucket获取应用程序的配置文件。前一段时间我可以获取配置文件,但现在我在尝试通过配置服务器url访问时出错。 应用yml: 当我试图访问网址的应用程序显示一个错误-未授权: 有人知道发生了什么吗?我已经检查了bitbucket上的所有凭据和url。