Spring-security: Consider adding switch to enable or disable OIDC nonce

Created on 4 Dec 2019  路  15Comments  路  Source: spring-projects/spring-security

@hejianchao No there isn't a setting/property available to turn it off. Are you having issues with it? Why do you want it disabled?

_Originally posted by @jgrandja in https://github.com/spring-projects/spring-security/issues/4442#issuecomment-561318109_

This issue was created for two reasons:

  1. Some cloud vendors do not fully support OIDC nonce, and an error will be reported: invalid nonce
  2. OpenID Connect Core 1.0, Section 3.1.2.1, "nonce" parameter:

nonce
OPTIONAL. String value used to associate a Client session with an ID Token, and to mitigate replay attacks. The value is passed through unmodified from the Authentication Request to the ID Token. Sufficient entropy MUST be present in the nonce values used to prevent attackers from guessing values. For implementation notes, see Section 15.5.2.

Also, as far as I know, the pac4j framework supports nonce settings (link).

oauth2 enhancement

All 15 comments

@hejianchao Regarding your comment:

Some cloud vendors do not fully support OIDC nonce, and an error will be reported: invalid nonce

If this is the case than the provider is NOT OpenID Connect compliant.

As per spec, in the ID Token section:

String value used to associate a Client session with an ID Token, and to mitigate replay attacks. The value is passed through unmodified from the Authentication Request to the ID Token. If present in the ID Token, Clients MUST verify that the nonce Claim Value is equal to the value of the nonce parameter sent in the Authentication Request. If present in the Authentication Request, Authorization Servers MUST include a nonce Claim in the ID Token with the Claim Value being the nonce value sent in the Authentication Request. Authorization Servers SHOULD perform no other processing on nonce values used. The nonce value is a case sensitive string.

The Authorization Server MUST include the nonce Claim in the ID Token if it was sent in the Authentication Request.

If you need to override the Authentication Request to not include the nonce parameter than you can supply oauth2Login().authorizationEndpoint().authorizationRequestResolver() a custom OAuth2AuthorizationRequestResolver that removes the nonce parameter. Take a look at the reference doc for an example of how to implement.

@jgrandja It works but not so convenient, For optional parameters like nonce, switches are a more convenient way. Anyway, thanks for your information.

@hejianchao

Some cloud vendors do not fully support OIDC nonce, and an error will be reported: invalid nonce

Which provider are you having this issue with? Could you provide more details around the error message? Is the error message being triggered by the provider or client?

The method that throws the exception is: org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider#authenticate:

// Validate nonce
String requestNonce = authorizationRequest.getAttribute(OidcParameterNames.NONCE);
if (requestNonce != null) {
    String nonceHash;
    try {
        nonceHash = createHash(requestNonce);
    } catch (NoSuchAlgorithmException e) {
        OAuth2Error oauth2Error = new OAuth2Error(INVALID_NONCE_ERROR_CODE);
        throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
    }
    String nonceHashClaim = idToken.getNonce();
    if (nonceHashClaim == null || !nonceHashClaim.equals(nonceHash)) {
                // Here thrown the exception because nonceHashClaim is null
        OAuth2Error oauth2Error = new OAuth2Error(INVALID_NONCE_ERROR_CODE);
        throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
    }
}

@hejianchao Which provider are you using?

I also ran into this issue using a proprietary in house IdP from a large organization. This IdP provides a limited openid feature set and does not support nonce parameters. It does however integrate with well known clients like Keycloak and others.

Although one can navigate around this problem as was suggested above. This is not a very clean solution. It would be nice to have a switch to disable requesting nonces.

@hejianchao @soarten I took a look at pac4j and I see that it provides a switch setUseNonce(true). I'm not a fan of this approach since every extended parameter would need an associated setUseExtendedParameter(true). And there are quite a few OIDC specific extension parameters. This will quickly make DefaultOAuth2AuthorizationRequestResolver unwieldy.

Instead of the switch approach, we're looking at introducing a Consumer<OAuth2AuthorizationRequest.Builder> #7748, that should allow easier customizations. For excluding the nonce, take a look at this test.

Let me know your thoughts.

@jgrandja Great, through Consumer<OAuth2AuthorizationRequest.Builder>, it can be more flexible and convenient for users to control the request, which solved my problem. Thank you.

Using switches for all sorts of options is far from ideal indeed, this would be a better solution!

@jgrandja I think there's a problem with OAuth2AuthorizationRequest.Builder.attributes method - it is called by default from DefaultOAuth2AuthorizationRequestResolver.resolve, setting up an attributesConsumer within the Builder which captures the attributes (it does putAll from captured attributes to a new map when the request is built, OAuth2AuthorizationRequest line 446).
If anyone uses the configurer (replacing the "putAll" attributesConsumer), those attributes are effectively lost.

@jadzie Can you put together a minimal sample or a test that reproduces the issue. This will make it more clear to me if there is an issue or not.

@jgrandja ok, will try to do it for tomorrow

@jgrandja https://github.com/jadzie/login-oidc-customizer-test I hope the readme is descriptive enough :)

Thank you for reporting this @jadzie and for the sample! This indeed is a bug. I logged #8177 and have a fix coming up.

@jgrandja glad I could help :)

Was this page helpful?
0 / 5 - 0 ratings