Does Spring Security OIDC client support automatic JWK key rotation? If yes how to configure refresh frequency?
The documentation states that "As the authorization server makes available new keys, Spring Security will automatically rotate the keys used to validate the JWT tokens.", but it doesn't provide information on how to configure refresh frequency.
Yes, Spring Security supports automatic JWK key rotation for OIDC clients. The functionality is contained in RemoteJWKSet (view source). Javadoc states:
Remote JSON Web Key (JWK) source specified by a JWK set URL. The
retrieved JWK set is cached to minimise network calls. The cache is
updated whenever the key selector tries to get a key with an unknown
ID.
Configuring the refresh frequency has already been discussed in 60409678.
Related
One question I’ve had recently about how the JWT middleware in asp.net core works is related to the Authority URL you can set if you want to verify tokens using an identity providers asymmetric keys (JWKS based presumably). All examples I’ve seen completely fail to explain what this authority URL should be. Some auth0 examples say it’s just your auth0 domain - but if that’s the case then how does the middleware locate the public key from this base URL? Every provider has a different convention for the endpoint where a JWKS can be found - so how does this work?
My requirement is that I need to use a home grown identity provider where the JWKS endpoint is totally different to auth0, okla, identity 4 or whatever other providers are using.
Is there some standard discovery mechanism that all these providers use that I’m not aware of? Do I need to have this same discovery mechanism in place I’m the in house identity web app for this middleware to work?
Thanks!
Generally, OpenID connects provider follows the standard and provides a discovery endpoint which includes all necessary endpoints and public key location information.
OpenID connect specification: https://openid.net/specs/openid-connect-discovery-1_0.html
Auth0 exposes OIDC discovery documents (https://YOUR_DOMAIN/.well-known/openid-configuration). These can be used to automatically configure applications.
https://auth0.com/docs/protocols/oidc/openid-connect-discovery
IdentityServer 4 allows to include extra endpoint to the discovery document. http://docs.identityserver.io/en/latest/topics/discovery.html
I've been going through this tutorial which shows how to secure a single page application using several scenarios going from simple to our own Authorization Server that delegates authentication to a provider. The first scenario uses the Authorization Code Grant to log the user in.
Suppose we replace Facebook's OAuth Server with our own in this case and configure it to return a JWT token.
Which OAuth flow should the SPA use if it wants to use the JWT token to secure requests through an edge server that load balances between resources servers?
Also how should spring boot / spring security be configured if we want to use the JWT token to replace the replace the default JSESSION and CSRF support in spring? IIUC the JWT token can be used as a replacement to both of these features.
Update
Based on Manish's answer assuming we are using OAuth 2 implicit flow we:
Put the #EnableResourceServer annotation on the Resource Server
Use an OpenID Connect client to implement the implicity flow
So once this is done are POST request secure assuming each request includes the JWT token as a Bearer Header, or do we need to also configure CSRF?
It will depend on how much your application is sensitive to security but Implicit flow is recommended for pubic client (SPA).
Tutorial is based Authorization Code flow and if you will replace Facebook with your STS, it will still use Authorization Code flow because #EnableOAuth2Sso store the JWT token on server and send the cookie to browser and it also uses refresh token to get the new JWT token. It is a customize flow to implement the Authorization Code flow with public client (SPA) based on API gateway pattern.
To implement the implicit flow - Do not use the #EnableOAuth2Sso at server side, just expose the REST API and secure it with #EnableResourceServer. And you need to use the oidc-client to implement the implicit flow link is here https://github.com/IdentityModel/oidc-client-js
CSRF protection is only required if you will store JWT token or session identifier in the browser's cookie.
I'm developing a REST web API that will be used by mobile app clients. I don't want any other client to be able to access the API. Should I just require a password/token that will be used by the mobile apps? Isn't there a way for people to find that password by decompiling my app?
Yes, you cannot create an app with a secret embedded and expect the secret to stay secret.
If you ship the app with the secret (token, user/pass, private key, etc), that information is available in the binary, and someone motivated could extract it.
The normal practice is to install the app, then let the user of the application log in, and store a unique credential for future requests.
You could use OWIN OAUTH where a user of the client is required to authenticate and a Bearer authorization token is returned to the client that must be passed in to all secure requests on the WebAPI (a secure request on the WebAPI uses the Authorize attribute)
Take a look at this link http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/#comments
For our portal development, we have decided to use Apigee to expose the web service to the portal. For which currently I am storing the API Key and Api URL in the properties file of the project. Can anyone help with some pointers on how else can I save the API key apart from the properties file.
Any pointers will be helpful in this case.
Regards
Aswathy
Typically the API key will be persisted by the the API consumer - usually an App of some kind. In case of Mobile Apps, each of them have an API Key or Client ID that is saved inside the app usually in some kind of secure data store. For other kinds of API consumers such as web apps the API Key may be persisted within a secure vault or an database that has some encryption features.
I assume your web portal app resides on a secure machine inside your enterprise and that this machine is access restricted. If this is the case bare minimum security is taken care of
However, If the key is a high privilege key and you can access APIs with key alone(ie without a secret), it is not advisable to keep it in plain text.
You can
1. Encrypt and store it in the config file and decrypt at runtime
2. Encrypt and store in Database or other secure storage you use for storing credentials.
If a client accessing an endpoint implemented as an ASP.NET Web API Controller over HTTPS provides a client certificate, that certificate is available through Request.GetClientCertificate. However, I'm wondering: is it possible to get information provided in the form of claims-based model that was integrated with the security model in .NET 4.5?
The main reason I'd like to do this is that I need different clients to be able to authenticate in different ways to access the same services, so I'd prefer to abstract away from specifics such as certificates. I want my controller to be able to base its decisions on the claims for the current user without concerning itself about the provenance of those claims.
I know there's a X509CertificateClaimSet type, which makes it seem like the natural flow would be:
Client certificate passed via TLS/SSL gets represented as an X509CertificateClaimSet through some sort of token mapping process (similar to how the incoming cookie generated by the federated provider you can use for ACS gets handled by the SessionSecurityTokenHandler
A claims transformation module (something derived from ClaimsAuthenticationManager and configured with a <claimsAuthenticationManager> element) inspects the claim set that came from the certificate, and transforms that into non-token-specific application-specific claims
The handler looks for the application-specific claims.
There's even a X509SecurityTokenHandler, which sounds like it should do this. However, as far as I can tell, that's designed for scenarios where the certificate-based authentication is handled within the messages being sent - it doesn't appear to have any support for the scenario where the proof of ownership of the certificate happened at the transport level, i.e. as part of the TLS/SSL handshake.
I'm wondering whether I need to write my own module to do this. In theory, it looks like it might be a case of just handling the AuthenticateRequest event, looking in the request for the certificate, constructing a X509CertificateClaimSet from the certificate if it's present. But...then what? Do I just create my own ClaimsPrincipal and replace the existing user? Or is there some 'correct' way to add the claims I've discovered to the set? (A client certificate is not necessarily the only source of claims - my application is already using claims that come from integration with ACS. Is there a standard mechanism for ensuring that all possible sources of claims are correctly merged?)
It looks likethe SessionAuthenticationModule (SAM) is the identity model component that currently provides a claims principal, and it just replaces the one that was previously in the context and also the current thread's user. But it appears to provide extensibility - if you override its ValidateSessionToken, that returns the set of ClaimsIdentity objects that make up the principal. So in theory, I could override that and add any additional claims at that point.
But I'm not sure that's the way to go. As far as I can tell, the SAM does this after the ClaimsAuthenticationManager has done its claims transformation. Or is claims transformation the wrong model to go with here?
Have a look here: client cert auth and claims generation is part of Thinktecture.IndetityModel.
If I were you, I would externalize the authentication - let some other services provide the authentication and just return SAML tokens with required claims.
This way, in your application you don't really think of certificates, you just expect some concrete claims from federated identity providers.
Then, you implement one of your identity providers to actually accept certificates but the outgoing SAML hides this implementation detail and translates the certificate to a claim set useful to your application.