Validating/Trusting Sharepoint Online STS token - authentication

I may have the wrong idea of how I should go about these things, but this is currently the case:
I have a WebApi service that accepts requests from Sharepoint Online (SPO), which have SAML2 token passed within. The SAML2 token is issued by SPO STS, and I will need to validate the token, and extract claims out of it.
My question is how do I validate the token? Is there a way to trust the STS somehow, so I can just verify the signature (possibly will have to decrypt the token as well) all in-place? If not, and I have to make another call to STS, what should be the endpoint to validate the token? I couldn't find much documentation on this.

If you're using O365 as STS or IdP and that provides the SAML2.0 Assertion to your service, then you have to get its X509Certificate (to verify the signature of received SAML2.0 Assertion) from metadata link: https://login.microsoftonline.com/<TenantDomainName>/FederationMetadata/2007-06/FederationMetadata.xml.
Make sure you retrieve X509Certificate from EntityDescriptor-> IDPSSODescriptor-> KeyDescriptor use="signing" -> KeyInfo-> X509Data-> X509Certificate.

Related

ASP.NET Core - having mTLS and OAuth2 at the same time

I have ASP.NET Core RESTful APIs and protect them with JWT token issued from Azure Active Directory. Any client who wants to call the endpoints should first acquire a valid JWT token from the AAD and send that as a Bearer token. My API internally should call an external API (internal to the organisation) to query some information and return it to the user. The external API requires mTLS as its security protocol.
My questions
Can I still have my Bearer authentication scheme against my APIs and at the same time have mTLS enabled in my API so it can communicate with the third API?
From my understanding, in TLS which mTLS is an extension of it, the client should verify the server's certificate. Does that mean, with every incoming request I should check if it's presenting the certificate? If so, then what would happen to the Bearer authentication scheme then?
In my head, I was hoping that I can just append the certificate to the requests against the third-party API and that should be it but based on question number 2 I seem to be wrong about it.
I'm a bit lost here and appreciate any advice on this.

how to send jwt authentication token in a rest request in asp.net core

Can someone tell me how to send jwt authentication token for every rest request send from asp.net core to the web APi,
Does there is need to create a secret key to sign the token signature?
Can we just send the token without signing the token.
This is very broad question.
Short answers:
Tokens are usually sent in cookies. Certain solutions also store tokens in browser localstorage or sessionstorage and then add the token in every request header
Yes, signing the token is mandatory. Otherwise, the server won't have a way to determine if the token has been tampered by an attacker or client. Signing is required for security
But there are much more to it. Refer to the following for details:
https://stackoverflow.com/a/54258744/1235935
https://stackoverflow.com/a/54011649/1235935
https://www.rfc-editor.org/rfc/rfc7519
https://www.rfc-editor.org/rfc/rfc6749

Thinktecture Identity Server: Securing Web APIs (Authorization Best Approach)

When protecting APIs using bearer token authorization:Is there a need to validate that the token was issued from my identity server or its already happening in the background and how do I do that?
What role do scopes play when it comes to bearer tokens?
In short, yes you need to validate that bearer tokens are issued by a issuer you trust. That means either by validating that it's signed by a trusted issuer, or making a API call to the isser you trust to ask it if it indeed is issued by the issuer you trust.
In practice: when talking about Katana, this is done by using a combination of [Authorize] filters/attributes and Owin middleware:
Option 1
The middleware from Microsoft:
app.UseOAuthBearerAuthentication(opts)
https://msdn.microsoft.com/en-us/library/owin.oauthbearerauthenticationextensions.useoauthbearerauthentication(v=vs.113).aspx
https://www.nuget.org/packages/Microsoft.Owin.Security.OAuth
Or, optionally, the middleware from Brock Allen og Dominic Baier:
Option 2
using the following abstraction that builts on top if Microsofts middleware (IF you need the extra features it provides):
app.UseIdentityServerBearerTokenAuthentication(opts)
Source: https://github.com/IdentityServer/IdentityServer3.AccessTokenValidation
NuGet: https://www.nuget.org/packages/IdentityServer3.AccessTokenValidation/
Scopes
When it comes to scopes & API access, scopes are something that represents the resources you want to protect. When a client asks for a access token, it can ask for a token to include a given scope. Your identityprovider then validates that this client is indeed allowed to receive a token with this scope. If successful, the end result is a token allowing the client to call a API using this token.
Since the API trusts token issued by this identityprovider (or token provider), all it has to do is to
Validate that that the token is issued by someone that API trusts
Check that the token contains the scope that represents it's resource

Client authentication in microservices using JWT and OpenID Connect

I've some questions regarding authentication in a microservices architecture. I've right now a monolithic application and my goal is to split the application in small microservices.
My bigest problem is for authentication (for now). After reading a LOT a documentation, It seems that the best solution is to use OpenID Connect to authenticate an user to retrieve a JWT that can by passed with the request to the microservices.
Also, to avoid having multiple endpoints, you can deploy and API Gateway to have only one endpoint for the end user. Ok, so now I've two questions with this architecture.
The standard flow for authentication will be :
An user contact my identity server in OpenID Connect with the implicit flow and get the id_token (JWT) and also the access_token. The user can now contact my API with this access_token. The API Gateway will valide the access_token with the identity server and also retrieve the JWT to add it to the sub request to the microservice API.
1/ How the API Gateway can get the JWT from the access_token? From what I red from the documentation (http://openid.net/specs/openid-connect-core-1_0.html), It can contact the "/userinfo" endpoint but It will get just the JSON format not the JWT...
2/ I want to allow authenticated calls between my microservices. So each microservice needs to be able to generate a JWT to contact other microservices directly. My first thought was to contact the identity server. But with the OAuth2 Client Credentials flow, I don't retrieve a id_token or a JWT. Just a classic OAuth2 access token without JWT. My second thought was that the microservice can directly sign its own JWT with a certificate issued by the same PKI as the one used by the identity server. That mean that a JWT can be sign by several certificats but from the same private PKI. When a microservice receives a JWT, It needs to be able to identify witch certificat was used to sign the JWT. I don't find anything on the RFC regarding this problem. I can add my own private claim in the token to have the certificate but after several days of browsing the web without seeing this kind of solution, I'm wondering if I'm not on the wrong path... To sum up, how can i perfom "User to service" authentication AND alors "service to service" authentication in JWT?
Thank you very much!
I am implementing a similar solution. Not sure if it will address to your question completely, but, I hope it helps:
You can implement a new authentication micro-service to convert your oAuth2 access token to JWT token. This microservice will also sign this JWT token.
Your API gateway will route all client requests to authentication service, which will validate this token from IDM and will convert it to a signed JWT token.
API gateway will pass this JWT token to other microservices which will validate the signature from Authentication Service's public key. If the signature validates, roles can be extracted out of it for authorization.
Each microservice can have its own IDM credentials configured and when it wants to call any other microservice, it can generate an access token and call Authentication Service to get JWT which can be passed in call to other microservices.

OAuth 2.0 Access token is not encrypted?

I am using System.IdentityModel.Tokens.jwt library for jwt access token and after i call WriteToken, I can get back the access token value from ReadToken in another program. So the access token is not actually encrypted by default?
Not encrypted, but it should be signed so as to prevent tampering.
The jwt library has a ValidateToken method to check the token signature is correct using your token signing cert or key.
You would need to rely on SSL for encryption.
This Blog post gives a bit more detail on the difference between signing and encrypting the token.
If you think it sounds a little crazy for Oauth2.0 to rely on SSL then you wouldn't be alone. Check out Eran Hammer's thoughts on Oauth2.0 and why he walked away from it.