okta/okta-spring-boot

Ensure standard Spring Security OAuth properties work with the Okta Spring Boot Starter

bdemers opened this issue · 5 comments

The okta.oauth2.* properties are just aliases to the equivalent spring.security.oauth properties.

(with the minor exception of a few okta specific properties like okta.oauth2.groups-claim)

We need to ensure these standard propties work, @mkheck reported this is no longer the case as of Okta Spring Boot Starter v2.0.0

Description: Method oauth2SecurityFilterChain in com.okta.spring.boot.oauth.OktaOAuth2AutoConfig$OAuth2SecurityFilterChainConfiguration required a bean of type 'org.springframework.security.oauth2.jwt.JwtDecoder' that could not be found.
 
Action: Consider defining a bean of type 'org.springframework.security.oauth2.jwt.JwtDecoder' in your configuration. Process finished with exit code 1

Using the properties similar to:

spring:
  security:
    oauth2:
      client:
        registration:
          okta:
            client-id: <my-client-id>
            client-secret: <my-client-secret>
        provider:
          okta:
            issuer-uri: https://<my-subdomain>.oktapreview.com/oauth2/default

The easiest thing to do, might be to setup another integration test module, and rerun the existing IT's using the standard Spring Security properties. i.e. copy the [test runner file] into another Maven module and change the properties (this needs to be done for both Servlet and Reactive stacks)

I've tried different scenarios with spring.security.oauth2 properties. And I must say that unfortunately, our application does not work without okta.oauth2.*. In this case, the OktaOAuth2Properties bean is empty and an exception is raised during validation and context loading. The appropriate corrections must be made to support spring.security.oauth2 properties. I can create a ticket and add it to my backlog for the next sprint. @bdemers please let me know if it makes sense for you.

Do you have a PR with the integration tests for this? What does the exception look like?

I haven't created PR for it. The easiest way to verify this (as you mentioned before) is to run existing integration tests with modified properties.
For example: I run the ResourceServerJwtValidationIT with properties:

  implicit-flow-local-validation:
    command: com.okta.spring.tests.oauth2.jwt.BasicJwtResourceServerApplication
    args:
    - --server.port=${applicationPort}
#    - --okta.oauth2.issuer=https://localhost:${mockHttpsPort}/oauth2/default
    - --spring.security.oauth2.resourceserver.jwt.issuer-uri=https://localhost:${mockHttpsPort}/oauth2/default
    - --spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://localhost:${mockHttpsPort}/oauth2/default/v1/keys
    - --spring.security.oauth2.client.provider.okta.authorization-uri=https://localhost:${mockHttpsPort}/oauth2/default/v1/authorize
    - --spring.security.oauth2.client.provider.okta.token-uri=https://localhost:${mockHttpsPort}/oauth2/default/v1/token
    - --spring.security.oauth2.client.provider.okta.user-info-uri=https://localhost:${mockHttpsPort}/oauth2/default/v1/userinfo
    - --spring.security.oauth2.client.provider.okta.jwk-set-uri=https://localhost:${mockHttpsPort}/oauth2/default/v1/keys
    - --spring.security.oauth2.client.provider.okta.issuer-uri=https://localhost:${mockHttpsPort}/oauth2/default
    - --spring.security.oauth2.resourceserver.opaque-token.introspection-uri=https://localhost:${mockHttpsPort}/oauth2/default/v1/introspect
    - --server.session.trackingModes=cookie

and receive IllegalArgumentException: issuer cannot be null from "com.okta.spring.boot.oauth.TokenUtil.jwtValidator(TokenUtil.java:97)". The exception starts from OktaOAuth2ResourceServerAutoConfig.jwtDecoder

I mentioned this at some point along the way, but the root problem here is that the issuer and other config are pulled from the OktaOAuth2Properties bean instead of the Spring equivalent like it should, this was likely changed recently when added support for opaque tokens. (just a guess, given we didn't have test coverage for this use case).

I think the first step is to create a branch to enable the ITs, then make sure the standard spring beans are used where an equivalent is used.

It's also possible, the spring properties will be null, this IS valid. For example, if spring.security.oauth2.resourceserver.* and okta.oauth2.issuer are NOT set, then this project should NOT configure a resource server.