okta/okta-spring-boot

Open id configuration for offline

venugeesala opened this issue · 5 comments

Hi,

Is there a way our SPringboot webapp can start without connecting to https://dev-xxxxxx.okta.com/.well-known/openid-configuration. Our server will be running without internet access inside our network. If we enable internet to the server and start the server and then we can turn off the internet and it works fine. Below is my properties file that I am trying to use for offline.

spring.security.oauth2.client.registration.okta.client-id=xxxxxxxxxx
spring.security.oauth2.client.registration.okta.client-secret=xxxxxxxxxxxxxxxxxxxxxxxxxxx
spring.security.oauth2.client.registration.okta.client-name=Access
spring.security.oauth2.client.registration.okta.provider=okta
spring.security.oauth2.client.provider.okta.issuer-uri=https://dev-xxxxxxx.okta.com

spring.security.oauth2.client.registration.okta.scope=openid,profile,email,address,phone
spring.security.oauth2.client.registration.okta.client-authentication-method=basic
spring.security.oauth2.client.registration.okta.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.okta.redirect-uri=https://dev-xxxxxxx.okta.com/oauth2/code/okta
spring.security.oauth2.client.provider.okta.authorization-uri=https://dev-xxxxxxx.okta.com/oauth2/v1/authorize
spring.security.oauth2.client.provider.okta.token-uri=https://dev-xxxxxxx.okta.com/oauth2/v1/token
spring.security.oauth2.client.provider.okta.user-info-uri=https://dev-xxxxxxx.okta.com/oauth2/v1/userinfo
spring.security.oauth2.client.provider.okta.jwk-set-uri=https://dev-xxxxxxx.okta.com/oauth2/v1/keys
spring.security.oauth2.client.provider.okta.userNameAttribute=email

Error stack:

Caused by: org.springframework.web.client.ResourceAccessException: I/O error on GET request for “https://dev-removed.okta.com/.well-known/openid-configuration”: dev-removed.okta.com; nested exception is java.net.UnknownHostException: dev-removed.okta.com
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:740) ~[spring-web-5.1.19.RELEASE.jar:5.1.19.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:666) ~[spring-web-5.1.19.RELEASE.jar:5.1.19.RELEASE]
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:307) ~[spring-web-5.1.19.RELEASE.jar:5.1.19.RELEASE]
at org.springframework.security.oauth2.client.registration.ClientRegistrations.getOpenidConfiguration(ClientRegistrations.java:106) ~[spring-security-oauth2-client-5.1.13.RELEASE.jar:5.1.13.RELEASE]
… 167 common frames omitted
Caused by: java.net.UnknownHostException: dev-removed.okta.com

This behavior is implemented by Spring Security and is used for OAuth2 client registration at server startup (See https://docs.spring.io/spring-security/site/docs/5.1.4.RELEASE/reference/htmlsingle/#startup-expectations-2). Okta's Org Authorization Servers support OIDC discovery via https://dev-xxxxxx.okta.com/.well-known/openid-configuration endpoint and Spring relies on this metadata to do JWT validation later at runtime.

For your case, I recommend you try the instructions at https://docs.spring.io/spring-security/site/docs/5.1.4.RELEASE/reference/htmlsingle/#webflux-oauth2-resource-server-jwkseturi. Let me know if that helps.

@venugeesala can you explain your use case a bit more? In order to validate tokens, a connection back to Okta is required. Even when doing only validating access tokens (JWT) locally you still need to periodically get a new set of public keys from a remote URL.

One suggestion I've seen is to limit traffic to specific IPs: https://support.okta.com/help/s/article/What-IP-addresses-ranges-should-we-whitelist-for-inbound-traffic-i-e-REST-API-calls-from-Okta-to-on-prem-JIRA-server?language=en_US

(Though this comes with its own set of challenges)

Closing this due to inactivity, feel free to reopen is needed.

Ways to register client:-

  1. Spring Boot makes a GET request to Okta (/.wellknown/openid-configuration) for open-id configuration to fetch metadata (like Authorization-server-url, client-id, redirect-url, user-info-url, token-url, jwk-set-uri ). Using this info spring boot creates ClientRegistration.

we can register our client explicitly in spring boot, so that Spring Boot don't make GET request to Okta for open-id configuration details.

@bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
}

private ClientRegistration googleClientRegistration() {
    return ClientRegistration.withRegistrationId("google")
        .clientId("google-client-id")
        .clientSecret("google-client-secret")
        .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
        .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
        .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}")
        .scope("openid", "profile", "email", "address", "phone")
        .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
        .tokenUri("https://www.googleapis.com/oauth2/v4/token")
        .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
        .userNameAttributeName(IdTokenClaimNames.SUB)
        .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
        .clientName("Google")
        .build();
}

Ways to register client:-

  1. Spring Boot makes a GET request to Okta (/.wellknown/openid-configuration) for open-id configuration to fetch metadata (like Authorization-server-url, client-id, redirect-url, user-info-url, token-url, jwk-set-uri ). Using this info spring boot creates ClientRegistration.

we can register our client explicitly in spring boot, so that Spring Boot don't make GET request to Okta for open-id configuration details.

@bean public ClientRegistrationRepository clientRegistrationRepository() { return new InMemoryClientRegistrationRepository(this.googleClientRegistration()); }

private ClientRegistration googleClientRegistration() {
    return ClientRegistration.withRegistrationId("google")
        .clientId("google-client-id")
        .clientSecret("google-client-secret")
        .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
        .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
        .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}")
        .scope("openid", "profile", "email", "address", "phone")
        .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
        .tokenUri("https://www.googleapis.com/oauth2/v4/token")
        .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
        .userNameAttributeName(IdTokenClaimNames.SUB)
        .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
        .clientName("Google")
        .build();
}