Reputation: 51
Spring boot 2.0.3 + Security + Oauth2 autoconfigure
I'm working with OAuth2 and microservices, I've created a microservice to generate the authorization tokens and another microservice as a client. Generation of tokens is working, but when I try to use this generated token on the client service to authenticate, it is not working.
Microservice that generates the tokens: localhost:9999
Token generated with url: estrutura:estruturasecret@localhost:9999/oauth/token
[
{
"key":"grant_type",
"value":"password"
},
{
"key":"username",
"value":"matheus"
},
{
"key":"password",
"value":"teste"
},
{
"key":"client_id",
"value":"estrutura"
}
]
return:
{
"access_token": "2e4c26b3-0fcf-493e-a255-6216b98811c5",
"token_type": "bearer",
"refresh_token": "5e33740a-ccb9-4ec1-94be-3a4643b8097a",
"expires_in": 42479,
"scope": "read write"
}
Customer Microservice: localhost:9090
@SpringBootApplication
@EnableResourceServer
public class ClientServer {
public static void main(String[] args) {
SpringApplication.run(ClientServer.class, args);
}
}
application.yml:
server:
port: 9090
servlet:
context-path: /client
spring:
application:
name: client-server
security:
oauth2:
client:
client-id: estrutura
client-secret: estruturasecret
access-token-uri: localhost:9999/oauth/token
user-authorization-uri: localhost:9999/oauth/authorize
resource:
token-info-uri: localhost:9999/oauth/check_token
logging:
level:
org.springframework.security: DEBUG
Error:
<error>invalid_token</error>
<error_description>Invalid access token: 2e4c26b3-0fcf-493e-a255-6216b98811c5</error_description>
Logs:
2018-06-26 11:24:42.641 DEBUG 18658 --- [nio-9090-exec-2] o.s.security.web.FilterChainProxy : /alunos at position 5 of 11 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
2018-06-26 11:24:42.641 DEBUG 18658 --- [nio-9090-exec-2] p.a.OAuth2AuthenticationProcessingFilter : Authentication request failed: error="invalid_token", error_description="Invalid access token: 2e4c26b3-0fcf-493e-a255-6216b98811c5"
2018-06-26 11:24:42.645 DEBUG 18658 --- [nio-9090-exec-2] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@1fa75b
2018-06-26 11:24:42.647 DEBUG 18658 --- [nio-9090-exec-2] s.s.o.p.e.DefaultOAuth2ExceptionRenderer : Written [error="invalid_token", error_description="Invalid access token: 2e4c26b3-0fcf-493e-a255-6216b98811c5"] as "application/xml;charset=UTF-8" using [org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter@30d6fa45]
2018-06-26 11:24:42.647 DEBUG 18658 --- [nio-9090-exec-2] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Upvotes: 3
Views: 11265
Reputation: 4532
I tried to replicate your use case: I develop an AuthServer with spring cloud security and an ResourceServer. The problem that I see using token-info-uri strategy is that spring in order to check the token use a RemoteTokenServices and it use a OAuth2RestTemplate in order to retrieve the token information said that if you want use the your configuration you have insert this kind of configuration like below:
@EnableOAuth2Client
@EnableResourceServer
@SpringBootApplication
public class HelloOauthServiceApplication {
public static void main(String[] args) {
SpringApplication.run(HelloOauthServiceApplication.class, args);
}
@Bean
public OAuth2RestTemplate oAuth2RestTemplate(OAuth2ProtectedResourceDetails resource){
return new OAuth2RestTemplate(resource);
}
}
Pay attention to @EnableOAuth2Client
and OAuth2RestTemplate
bean definition. Those configuration are used by spring in order to valid and refresh your token.
However in this way any resource server must be also a client application and in my experience it do not scale. My personal advice is to use the user-info-uri strategy. In this case spring will use a special endpoint in order to retrieve the user information. the configuration is very simple in your resource server you have define only @EnableResourceServer
like in your example in your yaml you can configure only the resource part like below
security:
oauth2:
resource:
user-info-uri: http://localhost:9090/account/userInfo.json
preferTokenInfo: false
The only additional develop is in your auth server that have to expose the user info in an endpoint like below:
@RestController
@RequestMapping("/account")
class UserRestFullEndPoint {
@GetMapping("/userInfo")
public Principal userInfo(Principal principal){
return principal;
}
}
I use this approach many times and I noted that it works very well and scale because in your resource servers you do not have define it like also a client app.
I hope that it may be useful.
PS: in your config you have forgot the http protocol:
server:
port: 9090
servlet:
context-path: /client
spring:
application:
name: client-server
security:
oauth2:
client:
client-id: estrutura
client-secret: estruturasecret
access-token-uri: http://localhost:9999/oauth/token
user-authorization-uri: http://localhost:9999/oauth/authorize
resource:
token-info-uri: http://localhost:9999/oauth/check_token
logging:
level:
org.springframework.security: DEBUG
Upvotes: 6