【问题标题】:Problem with access to Spring OAuth2 authorization server endpoint from java从 java 访问 Spring OAuth2 授权服务器端点的问题
【发布时间】:2019-03-24 20:04:39
【问题描述】:

我已经使用 Spring Framework 实现了授权服务器。我在访问授权服务器/用户端点时遇到问题,当我尝试从 java 访问它时,我总是收到响应 401 状态,但是如果我从 Postman 发送相同的请求,它就可以工作。我将 client_credentials 授权类型与 Bearer JWT 令牌一起使用。

邮递员屏幕:

使用来自 java 的代码:

RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidHJhbnNsYXRlLXNlcnZpY2UiLCJhdXRoc2VydmVyIl0sInNjb3BlIjpbIlJFQUQiXSwiZXhwIjoxNTUyMjg5MTk5LCJhdXRob3JpdGllcyI6WyJST0xFX0NMSUVOVCJdLCJqdGkiOiI2OTFjMzViNC1mMzM5LTQ1MTktYThlOC1mNzk2YzMzOGY4MzciLCJjbGllbnRfaWQiOiJrcnVrLWNoYXQtYm90In0.NJDy0FMMQTOSYrZmGiMB60JkwKR_03ino9i7I8FioWp8zzOfg51hcSYdJZJLF45xCWaHWdgS6-uNhXw-0mYO6LAlzx1a-DI2-DaYRnmoNG6gCPbNhifStjuFhNahzR4TlsuzvgI-oFpujX40rDYXUru-tmHf4zPFETFVHGKqpcnx2zjaY6U8UsgRRBIooYmI44Inh_9vsMQB75FaW0khZO2f8guR92J4FbTZprOmlA5qWRv4Sp0YBDxRFkaVntsfThHqsU11kiXso2FS2-1mu0rFVl-W0GYvVIdTCrLMDbgvHQkOPZpSLfyV5ObB-pjI0rR0yvU___TQXaDFn-1Kng";
headers.set("Authorization", "Bearer " +token);
HttpEntity entity = new HttpEntity<>(headers);
ResponseEntity<String> exchange = restTemplate.exchange("http://localhost:8090/user", HttpMethod.GET, entity, String.class);

例外:

08:14:26.366 [main] DEBUG org.springframework.web.client.RestTemplate - HTTP GET http://localhost:8090/user
08:14:26.380 [main] DEBUG org.springframework.web.client.RestTemplate - Accept=[text/plain, application/json, application/*+json, */*]
08:14:26.418 [main] DEBUG org.springframework.web.client.RestTemplate - Writing [{accept-encoding=[gzip], authorization=[Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidHJhbnNsYXRlLXNlcnZpY2UiLCJhdXRoc2VydmVyIl0sInNjb3BlIjpbIlJFQUQiXSwiZXhwIjoxNTUyMjg5MTk5LCJhdXRob3JpdGllcyI6WyJST0xFX0NMSUVOVCJdLCJqdGkiOiI2OTFjMzViNC1mMzM5LTQ1MTktYThlOC1mNzk2YzMzOGY4MzciLCJjbGllbnRfaWQiOiJrcnVrLWNoYXQtYm90In0.NJDy0FMMQTOSYrZmGiMB60JkwKR_03ino9i7I8FioWp8zzOfg51hcSYdJZJLF45xCWaHWdgS6-uNhXw-0mYO6LAlzx1a-DI2-DaYRnmoNG6gCPbNhifStjuFhNahzR4TlsuzvgI-oFpujX40rDYXUru-tmHf4zPFETFVHGKqpcnx2zjaY6U8UsgRRBIooYmI44Inh_9vsMQB75FaW0khZO2f8guR92J4FbTZprOmlA5qWRv4Sp0YBDxRFkaVntsfThHqsU11kiXso2FS2-1mu0rFVl-W0GYvVIdTCrLMDbgvHQkOPZpSLfyV5ObB-pjI0rR0yvU___TQXaDFn-1Kng]}] with org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
08:14:26.459 [main] DEBUG org.springframework.web.client.RestTemplate - Response 401 UNAUTHORIZED

org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 null
...
Process finished with exit code -1

端点配置:

@Configuration
@RestController
@EnableResourceServer
class ResourceServerConfiguration(@param:Value("\${security.oauth2.resource.id}") 
private val resourceId: String) : ResourceServerConfigurerAdapter() {

override fun configure(resources: ResourceServerSecurityConfigurer?) {
    resources!!
            .resourceId(resourceId)
}

@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
    http.antMatcher("/user")
            .authorizeRequests()
            .anyRequest()
            .authenticated()
}

@RequestMapping("/user")
fun user(principal: Principal, auth: Authentication): Principal {
    return principal
}
}

我做错了吗?

【问题讨论】:

  • 能否添加级别为DEBUG 的Spring Security 日志?如果您将 Postman 的请求添加为代码,也许它也有帮助(有一个链接 code 可以获取它)。

标签: java spring-security oauth-2.0 spring-security-oauth2


【解决方案1】:

我试图简化代码,所以我删除了 JWT 令牌转换器,现在我使用默认的 Spring OAuth 功能。我在身份验证服务器调试日志中观察到,如果我尝试从 java 发送标头,身份验证服务器端的请求中没有标头。但是当我从邮递员发送请求时,标题是可见的。

我尝试使用 RestTemplate 从 java 测试中执行 /user 端点,如下所示:

@Test
public void user() {
    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders headers = new HttpHeaders();
    String token = "11877200-61a4-4830-954e-b3530206bab9";
    headers.set("Authorization", "Bearer " +token);
    HttpEntity entity = new HttpEntity<>(headers);
    ResponseEntity<String> exchange = restTemplate.exchange("http://localhost:8090/user", HttpMethod.GET, entity, String.class);
}

我的授权服务器配置如下:

@Configuration
@EnableAuthorizationServer
@EnableGlobalMethodSecurity(securedEnabled = true)
class AuthServerConfiguration(@Lazy val authenticationManager : AuthenticationManager,
val customClientsDetailsService: CustomClientsDetailsService) : AuthorizationServerConfigurerAdapter() {

@Throws(Exception::class)
override fun configure(security: AuthorizationServerSecurityConfigurer?) {
    security!!
            .tokenKeyAccess("permitAll()")
            .checkTokenAccess("permitAll()")
            .passwordEncoder(BCryptPasswordEncoder())
}

@Throws(Exception::class)
override fun configure(clients: ClientDetailsServiceConfigurer?) {
    clients!!
            .withClientDetails(customClientsDetailsService)
}

override fun configure(endpoints: AuthorizationServerEndpointsConfigurer?) {
    endpoints!!
            .authenticationManager(this.authenticationManager)
            .tokenStore(tokenStore())
}

@Bean
fun tokenStore(): TokenStore {
    return InMemoryTokenStore()
}
}

身份验证服务器上的我的 WebSecurityConfigurerAdapter:

@Autowired
@Throws(Exception::class)
fun configureGlobal(auth: AuthenticationManagerBuilder) {
    auth
            .userDetailsService<UserDetailsService>(customUserDetailsService)
            .passwordEncoder(BCryptPasswordEncoder())
}

override fun configure(http: HttpSecurity?) {
    http!!
            .headers()
            .httpStrictTransportSecurity()
            .disable()
}

@Bean
@Throws(Exception::class)
override fun authenticationManagerBean(): AuthenticationManager {
    return super.authenticationManagerBean()
}

邮递员请求:

GET /user HTTP/1.1
Host: localhost:8090
Content-Type: application/json
Authorization: Bearer 7afcf301-c254-403b-a29b-5af0c42b80dc
cache-control: no-cache
Postman-Token: b0c4d661-20a3-49e3-958b-5cd9b1f08b15

来自身份验证服务器的带有邮递员请求的日志:

2019-03-24 12:56:41.250 DEBUG 14028 --- [nio-8090-exec-3] 
o.a.coyote.http11.Http11InputBuffer      : Received [GET /user HTTP/1.1
Content-Type: application/json
cache-control: no-cache
Postman-Token: ada0bb04-a7a3-43d0-aa84-6ced621d1e82
Authorization: Bearer 7afcf301-c254-403b-a29b-5af0c42b80dc
User-Agent: PostmanRuntime/7.6.1
Accept: */*
Host: localhost:8090
cookie: JSESSIONID=D782EDCB40FADAD8A634D40D95C0A870
accept-encoding: gzip, deflate
Connection: keep-alive
]

来自 java 客户端测试的日志:

12:58:52.468 [main] DEBUG org.springframework.web.client.RestTemplate - HTTP GET http://localhost:8090/user
12:58:52.480 [main] DEBUG org.springframework.web.client.RestTemplate - Accept=[text/plain, application/json, application/*+json, */*]
12:58:52.525 [main] DEBUG org.springframework.web.client.RestTemplate - Writing [{accept-encoding=[gzip], authorization=[Bearer 7afcf301-c254-403b-a29b-5af0c42b80dc]}] with org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
12:58:52.573 [main] DEBUG org.springframework.web.client.RestTemplate - Response 401 UNAUTHORIZED

org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 null

Process finished with exit code -1

来自身份验证服务器的日志与 java 客户端测试请求:

2019-03-24 13:03:01.399 DEBUG 14028 --- [nio-8090-exec-7] 
o.a.coyote.http11.Http11InputBuffer      : Received [GET /user HTTP/1.1
Accept: text/plain, application/json, application/*+json, */*
Content-Type: application/json;charset=UTF-8
User-Agent: Java/1.8.0_201
Host: localhost:8090
Connection: keep-alive
]

【讨论】:

    猜你喜欢
    • 2018-09-26
    • 2015-03-31
    • 2022-10-23
    • 2019-05-27
    • 2015-05-22
    • 2020-04-26
    • 1970-01-01
    • 2018-11-13
    • 1970-01-01
    相关资源
    最近更新 更多