IdentityServer: What is the difference between SigningCredential and DataProtection? - identityserver4

what is the difference between SigningCredential and DataProtection?
The signing credential is to sign de JWT
And the DataProtection to sign de cookies
Should I use two different certificates?

They are unrelated and both keys should be provided and configured for production deployments.
SigningCredentials is all about the keys used to sign the ID and access token. It's use by IdentityServer.
The Data Protection API also needs a encryption key and that is mainly used to encrypt the ClaimsPrincipal User and also optionally the tokens if the SaveToken option is set to true.
I did a blog post about the data for some time ago: Storing the ASP.NET Core Data Protection Key Ring in Azure Key Vault

Related

IdentityServer4 - Understanding flows and Endpoints. How is it related to OAuth and OpenIDConnect?

I am integrating the security aspect of webapplication. I have decided to use OAuth,
so we have a REST WebApi in AspNet Core 3.0, the client which is a SPA created in React, and the Identity Server 4.0 app which is also in AspNet Core 3.0.
I read that OAuth is created for Authorization and not for Authentication.
For Authentication, seems that exists something else called OpenIDConnect, so the first question that comes to my mind, and on which I cannot find an easy answer is: are OAuth, OpenIDConnect and IdentityServer related technology?
Which is the best solution for authentication, considering that I would like to create users in a SqlServer Database, and if it's possible I would like to use Entity Framework for the porpose?
The flow for my authentication would be:
User writes Username and Password, if they are right he receive the JWT Token, without redirecting him/her to the authorization page.
At this point the problem are:
which is the right endpoint to do this flow:
is it the /authorize or the /token endpoint?
I have a lot of confusion for the questions above.
The second thing, what is the best way to retrieve the user informations?
For example if my endpoint needs to understand from the logged in user what are his data, I think that or I retrieve from the endpoint or from the JWT token.
Even here I have no clue on which is the best.
I read that OAuth is created for Authorization and not for Authentication. For Authentication, seems that exists something else called OpenIDConnect, so the first question that comes to my mind, and on which I cannot find an easy answer is: are OAuth, OpenIDConnect and IdentityServer related technology?
That's right. OAuth was the first one introduced and allows the person requesting it access to the resources (its handing out access tokens). OIDC (OpenID Connect) on the other-side extends this concept by an identity, the authentication part.
The identity token verifies the identity of the person to your application. Instead of providing identity via username + password (i.e. user creating an account on your website), they get redirected to your authentication provider/app and enter their login there and you get an identity token in return (and/or an access token, depending on the flow and scopes you request).
The identity token is an JWT token (or reference token). The JWT token contains all of the users identity information required for your application (user id, email, displayname, age, etc.) and is cryptographically signed. Only the Identity Server knows the key used to sign it up and you can verify it with the public key from the OIDC (IdSrv here) provider.
Reference token works similar, but claims are requested on the server side and cached.
With identity token you can not access the users resources. Example: Facebook.
When you sign in your application with an facebook account, most page will only request identity token to verify that its the same user (instead of using a username / password combination). But with that one, the application can't access your facebook posts or do posts in your name.
If the application requests an access token (token scope), then also an access token will be returned (if the application is allowed to via allowed scopes). You will be asked to grant the permissions to the resources which the application requests.
With that token, the application can read your posts or post in your name.
Which is the best solution for authentication, considering that I would like to create users in a SqlServer Database, and if it's possible I would like to use Entity Framework for the porpose?
Doesn't really matter. Either one can be used, all you really need is the "sid" (subject id) claim and associate that one with your user.
Identity Server can issue both, depending on what the client asks (if client asks for id_token response type, it will receive an identity token, if it asks for token an access token. Both can be specified or just one).
At this point the problem are: which is the right endpoint to do this flow: is it the /authorize or the /token endpoint? I have a lot of confusion for the questions above.
/authorize is used to authorize the user (have him login, and send back to your website). Its used for so called interactive flows, where the user enters credentials
/token endpoint you can only retrieve a token (resource owner flow (username + password), client credentials (for machine to machine authentication), refresh token (to get a new access token by using an refresh token (if you asked for offline_access scope, which gives and refresh token)
The second thing, what is the best way to retrieve the user informations?
the /userinfo endpoint, see docs: http://docs.identityserver.io/en/latest/endpoints/userinfo.html
As the doc says to access that, the client needs to request the openid scope.
For example if my endpoint needs to understand from the logged in user what are his data, I think that or I retrieve from the endpoint or from the JWT token.
Yes you can retrieve it from JWT token, if you use JWT token. If you use reference token, its just an ID.
And last but not least the /introspection endpoint can be used to validate the token (if your consuming application has no libraries to decrypt and validate signature of the token.
If you can, its best to use the Identity Server client libraries (i.e. IdentityServer4.AccessTokenValidation package for ASP.NET Core or oidc-client for npm/javascript based applications) which should be picking up the correct endpoints, so you don't have to worry about it

Different authorities for user JWTs vs. client_credentials JWTs

I have noticed that when I obtain a JWT from Azure AD after logging on, the JWT specifies "https://login.microsoftonline.com" as the issuing authority. However, if I obtain a JWT using the client_credentials flow, the issuing authority is "https://sts.windows.net". Having dissimilar issuing authorities makes it difficult to configure an application to consume both kinds of JWTs, since the configuration process only allows you to specify a single authority.
Is there a reason why Microsoft uses different issuing authorities for JWTs? I assumed that it was because MSFT wants to segregate the two usage scenarios. That is, they want to discourage the creation of applications that switch between user-based and non-based security contexts. Is there some other reason I'm missing?
The changes in format of Issuer Authority value for the token that you're observing are most likely due to the different versions of token i.e. Azure AD v1.0 token or Azure AD v2.0 token (and probably not because you used client credentials flow or say auth code flow for acquiring access token for same application)
Azure AD v2.0 token - issuer format
https://login.microsoftonline.com/<Azure AD Tenant GUID>/v2.0
Azure AD v1.0 token - issuer format
https://sts.windows.net/<Azure AD Tenant GUID>/
Please look at this Microsoft Documentation - Access Tokens Reference - Sample Tokens
Notice this one has issuer format for each of the sample tokens there.
Also take a look at the important note in the same Microsoft Documentation Link shared.
As the documentation says, tokens are created based on the 'audience'. It also gives an example of using accessTokenAcceptedVersion.
You mention that even though you're using Azure AD v2 endpoint to acquire token with client credentials flow, you're seeing issuer as per v1 format.
I think that the application that you are acquiring the token for is important here, and if it accepts v1 token, then you will get back v1 token (even though you used v2 endpoint).
Also, if possible please share decoded tokens (minus sensitive info) in your question for more clarity.

How Do I Call Azure API Management From React?

My front end is using ReactJS and when I was testing locally I was using axios to make the calls. e.g.
axios.defaults.baseURL = process.env.REACT_APP_API_URL;
axios.get('/me').then((resp) => {
this.setState({identity: resp.data});
}).catch(() => {
console.log('Failed to retrieve identity');
});
I have now moved my API behind Azure API Management which is set up to require a subscription to use.
Part of the APIM policy checks the Active Directory group to validate the user is in the right group.
Therefore, I need to add 2 parts to my javascript
authenticate against Active Directory
send the Ocp-Apim-Subscription-Key in the header
react-adal looks like it might handle the login.
However, I can't work out how to modify my existing code to use it and send the header.
Its also not clear whether it is a security risk to hard code the Ocp-Apim-Subscription-Key in the javascript or if it should be retrieved on the fly.
If it should be retrieved on the fly, where should I store it and how should I retrieve it securely?
After you handle the login with react-adal, you can also modify how you send the subscription key to APIM.
APIM lets you define how you want to send the subscription key - custom HTTP header or the query string:
Both fields are text fields with pre-defined values which you can freely change (well keep in mind these are either HTTP header name or query string variable names).
To the question weather you should keep that secret. Well, you subscription key is your secret. And it is not short lived like the access token. So you should keep that as secret as possible and do not just put it in your JS code.
However I am not really convinced that a SPA application should use APIM subscription key to invoke the API. APIM subscription keys are just a symmetric keys used to authentication/authorization. As such (being symmetric keys) using these in a SPA application be would like using your username and password for the database in your SPA app. It doesn't really matter in what stage you put that key in the browser. The moment you put APIM subscription key in the browser, you cannot longer trust that key. Users can modify it, completely remove it, or use another valid subscription key if they find one.
For SPA application I would just use the Azure AD Authentication and shape the authorizations based on the bearer token. I suppose you already perform JWT validation checks in your policy? You can extract any and all claims form the token and you can make authorization decisions based on claim values.
If the React app is hosted in Azure App Service, then you should be able to register the React app with managed identity and use Azure KeyVault to keep the secret.
https://learn.microsoft.com/en-us/azure/key-vault/tutorial-net-create-vault-azure-web-app

Token based authentication in spa (React)

As I realized refresh token not supported in spa (react) .
Because it can not protect it .
So series of questions came up to me :
1 - Can we use long time access token in spa ? Is it secure?
2 - Is alternative solution for refresh token?
3 - Should we use the 3rd party identity server such as identityserver 4 or we can implement token generation Ourselves). What is best practice?
A bit late, but still...
You are right in terms of that refresh token should not be returned by Implicit Grant which is used to authenticate users in SPA applications. And yes, the limitation is due to a browser is unable to keep it private.
1 - Can we use long time access token in spa ? Is it secure?
We can, but whether it will be secure would depend on your application's security policy.
To keep it short, here is an example of how you can consider Access Token Lifetime to be specified for various security requirements.
2 - Is alternative solution for refresh token?
Yes, it is called Silent Authentication and briefly it looks like this:
a client (SPA app) obtains an Access Token and expires_in parameter
Identity Server provides an auth session (cookie) so the app can request a new token without providing credentials since it's already authenticated at Identity Server
in case of session's sliding expiration a client pings Identity Server to keep the session alive as long as needed
once the Acces Token becomes expired and auth session is alive (a check might be needed), a client requests for another Access Token (this is usually done in a setTimeout), but in this case providing a parameter to tell an Identity Server that consent screen should be dropped (usually it is prompt=none)
Resources:
Azure AD Silent authentication
Auth0 Silent authentication
3 - Should we use the 3rd party identity server such as identityserver 4 or we can implement token generation Ourselves). What is best
practice?
That would depend on the size of your application and whether you need just a token generation or something more (like Federated authentication out-of-the-box, various grant types, etc.).
For big enterprises (if there's no need to reinvent the wheel) it is always the best practice to use a production-ready 3rd party library (Identity Server 4 or OpenIddict) unless you have a small application (MVP, prototype, etc.).
Identity Server 4 needs some effort to configure it the right way and may simply be excessive. OpenIddict is a bit easier alternative.
Custom token generation is something that we used to do before Identity Server emerged. Today it is only a matter of having a quick solution for your custom authentication needs.
Worth to mention this project JWTSimpleServer for simple JWT authentication.

Secure REST API without user authentification (no credentials)

I've been struggling for 2 days now on how to secure a REST API without user authentification.
What does it mean ?
In my AngularJS application I identify an user by sending a GET request to an existing service (companydomain/userinfo) which I must use. I'm not sure how this work since I am not the author of this piece of code but the point is that I get the information about the user in the response as JSON (active directory name, phone in the company...).
This is all I have to identify an user.
What I did
Now, I found a lot of resources talking about OAuth, unique token, etc. but nothing seems to match with my issue. I implemented a token system but it's plain useless since I can't be sure of the authenticity of the requester.
User open the application. Application ask the service about the information related to the user. companydomain/userinfo
Application request a token to the server (nodejs & express), based on the information returned. /api/token/get/{user_info}
Server generates an unique token and store it in memory with expiration date and owner. The server also check in the table "authorized users" if the user exists (based on the active directory name), if not a new entry is added to it.
Application send the token along each request to the API. /api/entry/delete/{entry_id}
I think you see what is wrong here, an attacker could easily make a corrupted request to the API to get a legit token. So my question is :
How can I manage to secure my API since users don't use credentials to authentify ?
I hope my question is clear enough and at this point I am not even sure I can get around this issue without adding a credentials system.
You might want to look at Passport. It is a platform that allows you to easily add authentication to your application. There are many authentication strategies available. I am using Passport in a Node.js application implementing my own hmac strategy.
To authenticate, the client request includes an API ID to identify who the caller is and also includes an signature of a specified part of the message that includes things like the HTTP method, the API ID, a date value and some other header values, like maybe content-type. What data to include in the string to sign is up to you in your implementation, but the client and server must create and sign the same strings for the authentication to work. The signature is created by doing an hmac hash of the string using a shared secret.
On the server side, you use the API ID to retrieve the shared secret (possibly from a database or the filesystem) and perform the same hash on the request. If the hmac values match then you've authenticated the request. To prevent playback attacks, the date is included in the signed part of the request and must be within a certain window of the server's current time. For example, you might reject the request if the timestamp is more than 30 seconds old.
To enable a new user of your API, you generate a new API ID and shared secret. You give both of those to your API user and you store them for look up in your database or filesystem. The user must sign the requests with the shared secret and include the ID in the request.
The Hawk strategy provides much of this functionality, but we decided to roll our own hmac strategy.
Because you say that the user info endpoint returns active directory name, I assume you're on the Windows platform.
If so, why not use Windows integrated authentication (Kerberos) to authenticate your users without asking them for credentials? This will only work within your active directory domain, but is completely transparent to your service.
You can still call the user info endpoint and verify that the info it returns is for the same user that is calling your REST service.
If you need to call services that do not support Windows integrated auth, you could generate a security token (sign it to guarantee integrity) and make the other services trust this token.

Resources