I've begun an implementation using the OpenID Connect Implicit Flow - I've retrieved my access token and ID token in my browser based javascript app, and now I need to protect the resource on my ASP.NET Core Web API so it can only be accessed via a valid access token from a user with a specific claim.
What middleware do I use to validate the token(s) and determine the user and their claims so I can then allow or deny them access to the resource they are requesting?
I've looked at OpenIdConnectAuthentication middleware, however the only implementation examples I've seen use a SignInScheme of "Cookies", not the Bearer token that my js app is providing.
Thanks
What middleware do I use to validate the token(s) and determine the user and their claims so I can then allow or deny them access to the resource they are requesting?
If your authorization server issues JWT tokens, you can use the JWT bearer middleware developed by the ASP.NET team: https://github.com/aspnet/Security/tree/dev/src/Microsoft.AspNetCore.Authentication.JwtBearer.
app.UseJwtBearerAuthentication(new JwtBearerOptions {
Authority = Configuration["jwt:authority"],
Audience = Configuration["jwt:audience"]
});
You can find a sample here: https://github.com/aspnet/Security/tree/dev/samples/JwtBearerSample.
Related
Currently I have an SPA with multiple springboot microservices at the back (Resource Servers). Authentication and Authorization happens in the back using a Spring Oauth2 Server that serves a "Login Page" (Consent Screen) . Inside the Oauth server there is a ldapAuthentication provider that delegates authentication to an Active Directory and the rest (user detail and authorities) is fetched from a jdbc source from a custom data model (groups and privileges).
I have the requirement to start using Okta (enterprise). Conceptually speaking, do I have to remove completely the Spring Oauth Server and do everything with Okta regarding Authentication and Authorization? What would be the flow? What happens with the Bearer Token that I currently use? What happens with the introspection of each resource server when applying security access to requests? I am pretty confused what should be the Spring solution for Okta comming from a Spring Oauth Server.
Yes, Okta and Spring OAuth server are both authorization-servers, so you'll probably replace one with the other. The flow will be the same standard OAuth2 authorization-code flow:
"rich" client redirects users to authorization-server for authentication (Okta instead of spring authorization-server)
authorization-server redirects users back to "rich" client with authorization code
"rich" client exchanges authorization-code for access and optionally refresh and ID tokens
"rich" client sends request to resource-servers with access-token as Bearer Authorization header
resource-servers validate access-tokens and retrieves token claims (either with JWT decoder or introspection) and then evaluates if access should be granted based on token claims
You'll have to refer to Okta docs to add required roles (or groups or authorities and whatever you need in your resource-servers security expressions and that is stored in your LDAP and "JDBC storage") to Okta access-tokens.
If you really have configured your resource-servers with token introspection, you might have to switch to JWT decoding (I haven't search much, but it seams that Okta's introspection endpoint just returns a boolean: isTokenValid). You'll save a lot of resources in the process as JWT validation & decoding happens on resource-server only (it does not require a round-trip to authorization-server for each request as introspection)
You can replace your Spring OAuth server with Okta Authorization Server, which will require all your micro-services to change their configuration to do the introspection against Okta endpoints. Bearer tokens would be minted by Okta too.
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 am building a website and I am using asp.net web api 2 with Identity framework and Oauth for Authorization .
I would like to know the differences between default web token and json web token (JWT) and in which cases we use each one?
JSON Web Token (JWT) [JWT] is a JSON-based [RFC7159] security token
encoding that enables identity and security information to be shared
across security domains. A security token is generally issued by an
Identity Provider and consumed by a Relying Party that relies on its
content to identify the token's subject for security-related
purposes.
The OAuth 2.0 Authorization Framework [RFC6749] provides a method for
making authenticated HTTP requests to a resource using an access
token. Access tokens are issued to third-party clients by an
authorization server (AS) with the (sometimes implicit) approval of
the resource owner. In OAuth, an authorization grant is an abstract
term used to describe intermediate credentials that represent the
resource owner authorization. An authorization grant is used by the
client to obtain an access token. Several authorization grant types
are defined to support a wide range of client types and user
experiences. OAuth also allows for the definition of new extension
grant types to support additional clients or to provide a bridge
between OAuth and other trust frameworks. Finally, OAuth allows the
definition of additional authentication mechanisms to be used by
clients when interacting with the authorization server.
About default web access , i think it is only a general token.
Let's take an example where we have an SPA accessing an API using the OIDC implicit flow.
Since OAuth scopes are coarse-grained, it is often necessary to perform additional authorization on the resource servers. This can be the case for example when accessing dynamic resources (e.g filesystem) via an endpoint - where access is restricted by permissions tied to the userId, but it is not practical to use OAuth scopes only because of the dynamic nature of the resources.
In these cases the endpoint itself can be protected by an OAuth scope, while access to the resources that the endpoint operates on (e.g files) will be granted based on the userId. Hence the user's identity must be securely sent in the API request.
An obivious choice can be to send the ID token that was obtained when authenticating, together with the access token that was obtained at the same time.
There is a standard way for sending the access token in a HTTP request (the Authorization header), but is there one for the ID token? Or should I just make up a header name like 'X-Identity'?
To answer the question: there is no standard for passing the ID token in an HTTP request.
But arguably there doesn't need to be one: in this case you may not need OpenID Connect since scopes are not the only information that can be associated with an OAuth 2.0 access token as you seem to suggest.
You can "associate" the userId with the access token so that the Resource Server can grant the Client access to the protected resource based on the identity of the user who granted the access token to the Client.
The "association" is implementation dependent: the access token can be a JWT that contains the userId claim or the access token can be an opaque value that the Resource Server can introspect/validate at the Authorization Server to obtain the information associated with it.
Instead of passing it in the header, you can pass it as a query parameter:
curl "https://resourcePath?auth=<ID_TOKEN>
Here's the reference:
https://firebase.google.com/docs/database/rest/auth#authenticate_with_an_access_token
I am using Visual Studio 2015 Enterprise Update 1 and ASP.NET 5 rc1-final to build an endpoint that both issues and consumes JWT tokens as described in detail here. In this approach we have a single project that 'does it all' - the project uses OIDC to issue tokens, JWT bearer authentication to validate them and then guards access to various controllers using the Authorize attribute - all in the same project.
Now we would like to refactor this solution by creating an OIDC authorization & authentication endpoint that only issues and validates tokens. Then we want 'n' additional endpoints that rely on that OIDC endpoint as a central authority for authenticating tokens. This will allow us to stand up additional endpoints on our growing service backbone without having to code the authorization & authentication into every endpoint.
While I understand how to configure OIDC to issue tokens from one endpoint, it's not entirely clear how I would point my other endpoint to the OIDC endpoint for token authentication. Presently JWT authentication and OIDC are simultaneously configured in the middleware 'Configure' method so I'm guessing perhaps on all the subordinate sites I would have a small piece of code in calling app.UseJwtBearerAuthentication simply pointing the JWT middleware to the OIDC endpoint? If this is the case there's still a bit of magic taking place with the app.UseJwtBearerAuthentication that uses OIDC to allow IdentityModel to use HTTP, so I'm not clear if I would need this on the subordinate servers also.
Any advice on how to establish a single OIDC authorization & authentication endpoint and then have 'n' subordinate endpoints point to that endpoint for authentication of JWT tokens would be very much appreciated.
Separating the resource server role (i.e the API) from the authorization server role is definitely possible with ASOS.
When opting for JWT tokens (instead of the default encrypted tokens), you need to ensure the audience is correctly added to the authentication ticket by calling ticket.SetResources, so the JWT access token gets the appropriate aud claim, containing the identifier associated with your resource server (i.e API):
public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context) {
var identity = new ClaimsIdentity(context.Options.AuthenticationScheme);
identity.AddClaim(ClaimTypes.NameIdentifier, "[unique identifier]");
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new AuthenticationProperties(),
context.Options.AuthenticationScheme);
// Call SetResources with the list of resource servers
// the access token should be issued for.
ticket.SetResources("resource_server_1");
// Call SetScopes with the list of scopes you want to grant.
ticket.SetScopes("profile", "offline_access");
context.Validate(ticket);
return Task.FromResult(0);
}
In your API app, you just have to set the options.Audience property with the identifier used in the authorization server, and it should work:
app.UseJwtBearerAuthentication(new JwtBearerOptions {
AutomaticAuthenticate = true,
AutomaticChallenge = true,
Audience = "resource_server_1",
Authority = "http://localhost:61854"
});
I would have a small piece of code in calling app.UseJwtBearerAuthentication simply pointing the JWT middleware to the OIDC endpoint? If this is the case there's still a bit of magic taking place with the app.UseJwtBearerAuthentication that uses OIDC to allow IdentityModel to use HTTP, so I'm not clear if I would need this on the subordinate servers also.
The JWT bearer middleware automatically retrieves the cryptographic key used to sign the access token from the authorization server mentioned in the options.Authority property, by making an HTTP call to the configuration metadata endpoint: you don't have to configure anything, even if the API project is separated from the authorization server app.