Проблема с доступом к конечной точке сервера авторизации Spring OAuth2 из Java - PullRequest
0 голосов
/ 11 марта 2019

Я реализовал сервер авторизации, используя Spring Framework. У меня проблема с доступом к серверу авторизации / конечной точке пользователя, я всегда получаю статус ответа 401, когда пытаюсь получить к нему доступ из Java, но если я отправляю тот же запрос от 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 голосов
/ 24 марта 2019

Я попытался упростить код, поэтому удалил оболочку токена JWT и теперь использую функциональность Spring OAuth по умолчанию. Я наблюдал в журналах отладки сервера аутентификации, что в случае, когда я пытаюсь отправить заголовки из java, в запросе на стороне сервера аутентификации нет заголовков. Но при отправке запроса от почтальона заголовки видны.

Я пытаюсь выполнить / пользовательскую конечную точку из теста Java, используя RestTemplate, как это:

@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
]
...