Search code examples
oauth-2.0spring-webfluxopenid-connectclient-certificates

OAuth2 Client Certificate Credentials and OIDC Issue


My company uses PingFederate server for implementing Oauth2 token A&A and we also use PKI certificate-based authentication for which the server is configured.

We have a java Spring Boot Reactive web API that is configured to authenticate via Oauth2 tokens. It implements the authorization code flow.

So here is the problem.

When the API makes the call to the Oauth2 server for an authorization code, the request is made with the client cert configured for API, not the user cert making the call. The code is returned, and I can use that to retrieve the access token and identity token.

The issue is that the identity token contains claims about the client app and not the user.

Is there a way to configure the reactive API to pass the user cert rather than the API cert?

I can configure the API to use my personal user cert and it will return the correct identity token, but I need to be able to extract the user cert from the agent and pass that along with the request.


Solution

  • Usually an authorization code flow using client certificates for authentication works like this:

    FRONT CHANNEL REQUEST

    This request does not usually use client certs or APIs. Instead, the client sends an authorization request on the system browser and the user authenticates by some method to identify herself.

    This results in a subject claim being calculated. The subject is stored by the authorization server, which returns an authorization code in the authorization response.

    BACK CHANNEL REQUEST

    The client then sends the authorization code in a token request to the authorization server's token endpoint. An mTLS channel can be used, to provide proof of ownership of a client certificate. A browser based app usually does so via a backend component that supplies the client cert.

    Tokens issued then contain a subject claim of the user, even though a backend component supplied the client cert.

    YOUR QUESTION

    From your question a couple of things feel a bit non-standard - maybe you could improve your question?

    • What method is used for user authentication? Eg do you use passwords, passkeys, a custom authentication method etc? The authentication method is what calculates the subject in tokens.

    • Are you using client certs to authenticate the client at the token endpoint, or to authenticate the user somehow at the authorize endpoint? If the latter then much of my answer will need updating.

    • Are you trying to double hop client certificates from the client to your API to the authorization server? If so that will not work.

    • Why is your API initiating the code flow? Is it a backend for frontend? How does the front channel request work? Eg. does the API redirect the browser?

    PRESENTING USER LEVEL CERTIFICATES

    If you must deploy user-level client certificates then your API does not provide much of a security role for the frontend. Instead, there are a couple of options you can consider for your solution.

    DIRECT MUTUAL TLS

    The browser based app can call the authorization server's token endpoint with the client certificate directly. If the authorization server is hosted behind an API gateway, you would configure the gateway to use TLS passthrough.

    MUTUAL TLS TERMINATED AT PROXY

    If the authorization server is hosted behind an API gateway, then the gateway can verify a certificate sent by the browser based app, and then call the authorization server. You then need to ensure an attacker cannot gain access by bypassing the gateway.