3

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

Documentation: https://docs.spring.io/spring-security-oauth2-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-security-oauth2-authorization-server

1 Answers1

6

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
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Valerio Vaudi
  • 4,199
  • 2
  • 24
  • 23
  • Great answer with details. Can one use third party Autorization Server (like Azure AD etc.) and still have similar approach? – Turcia May 14 '21 at 10:56
  • hi Turcia I never tried with other providers but my personal suggestion is to try the newest spring security oauth2. The library under discussion in the question is based on spring cloud security and SSO capability are deprecated and removed on latest spring boot version – Valerio Vaudi May 16 '21 at 14:44
  • I mean the answer is fine for spring cloud security and legacy oauth2 library but those library are deprecated in spring in favour fo the latest spring security support for oauth2 and openid connect – Valerio Vaudi May 16 '21 at 14:46
  • Thank you Valerio, I'll take a look. – Turcia May 17 '21 at 16:03