从Java访问Spring OAuth2授权服务器端点的问题

时间:2019-03-11 07:22:07

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

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

邮递员屏幕: enter image description here

从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
}
}

我做错什么了吗?

1 个答案:

答案 0 :(得分:0)

我试图简化代码,所以我删除了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
]