.NET 5 Web API Jwt Token from external issuer - jwt

Im trying to make an .NET 5 Web Api works with Jwt Bearer token. I want some operations to be secured by using a token that comes from another issuer. The token would be generated by MS Azure AD. The application will read the token from the request header, validate it and extract the user's roles for more validations. The app shoudn't be the issuer of the token.
Is this possible? I tried so many ways to make this works without success. I setup Swagger to use OpenId Connect with Microsoft Azure and then the bearer is used to call the secured operations but always got errors. Now I don't understand how Dotnet Core Authencation and Authorization works.
Thanks in advance!

That will definitely work OK but requires an understanding of the science:
AZURE AD TOKENS
I would first look at the JWT in an online viewer. There is a known issue with the default setup where you get JWT access tokens that cannot be validated. See Step 3 of my blog post for details.
UNDERSTAND PRINCIPLES
Validating a JWT involves the general steps in this blog post. Once you understand this it will hopefully unblock you.
C# JWT ACCESS TOKEN VALIDATION IN APIs
The Microsoft framework often hides the required logic, which doesn't always help, and the option I prefer is to validate JWTs via a library.
Aim to understand how to use the JwtSecurityTokenHandler class to validate a JWT manually, eg in a console app. Maybe borrow some ideas from this C# code of mine.
C# AUTHORIZATION
Once JWT validation works, the next step is to use the details in the ClaimsPrincipal to determine whether to allow access to data. I would get on top of the JWT validation first though.

Related

Use single JWT Token with 2 different applications

I have 2 different applications.
Let's say A & B.
A is being used for login/signup and users related activities.
And It is also used for Generating JWT Token and validation as well.
Now, the other application B is used for some very specific operations.
I want to use the same JWT token I generate from application A to validate users and extract useful information from the token.
Can someone please suggest to me what design should I follow?
Should I use 2 different JWT validators?
Actually is nothing wrong to use service A as an Authorization Service that issues JWT tokens and the B service as a resource service
here is a posts described how to do it in ASP.NET Web API
Token based authentication

What is the advantage of a custom API in Auth0?

Question
I got a problem with understanding some basic thing about auth0, probably someone can help me out.
In the tutorial SPA + API one of the first lines in the TDLR is this:
Both the SPA and the API must be configured in the Auth0 Dashboard
I dont understand why I need to configure the API on Auth0. My code seems to work so can anyone help me understand if I do something wrong or what the advantages are if I actually add a custom API in my dashboard?
Setup
SPA (React)
Auth0
REST API (ktor)
What I do
Created a SPA on Auth0
Login on my SPA through Auth0 to get a JWT (google token)
Sending the JWT as authentication bearer in my calls to the REST API
REST API verifies the JWT token with a JWK provider using the Auth0 url mydomain.eu.auth0.com/.well-known/jwks.json.
Authentication seems to work
Great question, I am assuming that your authentication request includes audience parameter which represents your custom API(Rest API)right now. In oauth2 terms, it is called Resource Server. Each resource server can have many permissions which you include in the scope when initiating the authentication request. Let's step back and talk about the token format. Auth0 issues token in two formats:
Opaque strings: When not using a custom API
JSON Web Tokens (JWTs): When using a custom API
https://auth0.com/docs/tokens/reference/access-token/access-token-formats#how-does-all-this-affect-the-token-format-
As explained above link, the token format depends on the audience (Custom API) parameter. Therefore, when the authentication request includes audience, auth0 issues JWT token with all necessary permission. Then, you need to validate the JWT token in your API server before returning the resources to your front end client.
It should make sense why you need to create custom API in auth0 and define permissions. If you do not create custom API in auth0, there is no way to know what kind of permission you need in the token which will generate an error(invalid audience specified)

registering a rest API with OAuth

I have written a web application which makes REST API calls to a message broker. The message broker contains already written REST APIs to which can be used to get message broker data. The message broker is written in a way in which each REST API call sends the user name and password which is encoded with base64. I need to make a login to my web app and authenticate it with OAuth.Does anyone know how to do this? How to authenticate the REST APIs with OAuth?
Step 1: Add OAuth 2.0 to your web server. This is very standard with lots of libraries available. You did not specify the Identity Provider that you will use (Google, Facebook, Auth0, Okta, etc), but each vendor has documents and libraries for you to use in your desired language.
Step 2: Add an Authorization Header to your API calls. The standard method is to add the HTTP header Authorization: Bearer access_token when making an API call.
Step 3: Add OAuth token verification to your API. When your API receives a request, it extracts the Authorization header and verifies the Bearer token. How this is done depends on the Identity Provider. For example, some vendors provide a Signed JWT (which you verify with the vendors public certificate), others provide an opaque access token (which you verify by calling the vendor's token endpoint). Add internal caching of tokens so that you don't need to verify on every API call.
If you understand OAuth 2.0 the above steps are straightforward to implement. If you don't Oracle has a set of videos which are excellent for getting started understanding OAuth.
Oracle Cloud Primers
If your desired OAuth implementation does not require users logging in and is a server to server service that you control on both ends, then you can use just part of OAuth which is Signed JWT (JWS). You create a Json data structure with your desired content and sign it with a private key. This creates a token that you can use in the above steps. You would then validate the token using your public key. You can use self-generated keypairs generated by OpenSSL or similar products for your signing and verification.

OpenIdConnect: how to add additional claims in the token?

I'm quite new to OpenIdConnect so excuse me if i still miss some basic concept.
I have a SPA-style web application I'm developing for my company (AspNet Core + Aurelia).
I want to use AzureAD via OpenIdConnect for authentication and authorization, everything works very well so far i'm able to obrain a token and sign in.
the problem is that my application needs to provide to the client's browser some app-specific claims like: can read X, can edit Y...
if i add these claims to the JWT token provided by AzureAD obviously it will became invalid, as the signature will not match the content.
if i generate a new token with the new claims, but signed with the app key, obviously it will be a different token valid only in the context of my app (what if I'll later need to access some other resource using the AzureAD token?, is it a good idea to insert the AzureID token as claim of the newly issued token?)
Are there something I'm missing in the OpenConnectId? or is there a way to add claims to a token issued by a 3rd-party provider like AzureAD while keeping the token valid? Maybe a way to ask AzureAd to add claims to the token and re-sign it?
I think a good way to solve this situation may be to obtain an access_token for my own application's api (from my app backend) in exchange of the id_token provided by azure (after its validation)
so the application frontend in the browser will own two tokens and it will be able to use the correct one for each type of request.
there are some standardized flow that are quite similar to this but not exactly the same.
You could try to use a custom claim mapping policy. This is documented here.
This feature is used by tenant admins to customize the claims emitted in tokens for a specific application in their tenant.
As far as I can understand, this is still in preview stage. So it may require some trial and error verification.
Alternatively, you can define some policy in your application itself. Given that you know client IDs from your application (hence you require to use them for OpenID Connect requests), you may create a simple policy to check tokens and perform verifications.

Authentication with Akka-Http

We're developing an iOS app, where the user needs to authenticate using email+password (or mobile number). Our backend is made of a couple of microservices using Akka-Http. It needs to be fast, scalable, concurrent, and the authentication+authorization should work across our multiple services.
I'm trying to figure out which authentication method to use.
Akka-HTTP currently offers Basic Auth and a partial implementation of OAuth2.
So at first we were considering Basic authentication (too simple and not enough functionality), Oauth1 (too complex), so we moved towards OAuth-2.0 because it is sort of a standard.
Then we considered AWS Cognito because it combines Oauth-2.0 and OpenID Connect which gives the authentication mechanism that OAuth2 lacks.
http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html
Then we realised that OAuth2 is just for authentication using a third party - when in fact we don't need a third party authentication provider - maybe we need to do it ourselves, and using Cognito is an overkill that would create extra api calls outside our microservices...
So I read a little bit about creating our own custom auth provider, using WSSE specs:
http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html
And I also found this example using Spray, but I'm sure it's not that different from Akka-Http:
http://danielasfregola.com/2015/06/29/how-to-create-a-spray-custom-authenticator/
It looks too simplified and doesn't have token expiration...
So my question is, am I missing something? What method should I chose and where can I find examples for it?
I feel like I'm going in circles, we're gonna have to write our own custom authentication provider from scratch, which kinda doesn't make sense. After all almost everybody needs authentication and it should be a standard.
I've recently been using SoftwareMill's akka-http-session library and found it simple and easy to integrate. It has support for case class based sessions, JWTs, refresh tokens with pluggable storage, using headers and CSRF tokens as well as some nice simple directives for use in routes.
My solution for user registration has been to use Keycloak, an open source server which can handle user registration and do OIDC, OAuth2 style login. It reduces the amount of code I have to write, and the code is more secure than if it rolled it myself.
I then write my application as Scala backend that's purely a JSON API and a React/Javascript rich frontend in front of that API. In this configuration the authentication is handled completely on the front-end (and can be done in your iOS client). The front-end app redirects the user to Keycloak and when the user comes back they have a signed "JWT" token you can keep in a cookie.
That JWT token is attached to all API calls made the JSON backend as an Authorization Bearer token HTTP header. The token itself contains the users email address and is cryptographically signed by the Keycloak server.
The backend gets the JWT token in the HTTP header, extracts the email address and verifies the token is cryptographically signed by the keycloak server.
It's performing a certificate check on the keycloak server and can cache it's certificate. So it doesn't need to have roundtrips like OAuth, or any upstream calls to make.
This gives us simple, low-chance-of-failure, high speed authorisation in our JSON backend API and means we aren't putting secrets in the iOS client, or rolling too much of our own code.