Thinktecture Identity Server: Securing Web APIs (Authorization Best Approach) - asp.net-web-api2

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

Related

Can I use OAuth for authentication for trusted client (mobile app)?

I know how OAuth2 and OpenID Connect works. But there is still some confusion bothering me.
We develop our own Auth Server, service API and mobile app. So, the client app is trusted and we use "password" grant type. The app user repository follows the same user database in auth server.
Our customers login to the app by username/password. The app then submits the user credential to the Auth Server token endpoint, which will return the (bearer) access token and ID token (JWT) to the client.
The ID token contains basic user information so that the app can greet user like "Welcome Tony Stark!".
The access token can be used to access API (e.g. update user profile).
OAuth by design is not a tool for authentication. Ref: https://www.scottbrady91.com/OAuth/OAuth-is-Not-Authentication
My questions are
1) Do we need to verify the signature of the ID token if the client only is only interested to get the user information? Also note that the ID token is coming from the token endpoint via https connection.
2) Let's forget about the ID token. Can we treat the user has passed the authentication check (i.e. login success) if the client obtains an access token from the Auth Server? This flow is very similar to simple password login without OAuth.
3) The client can access protected APIs with the access token. Without access token, the client can only invoke some public APIs. Is it equivalent to what can be done with and without login? It seems the access token can be treated as "login session cookie".
4) There is no 3rd party involvement in my case. Everything (client, auth server, service API) is developed and owned by the same organization. Does it still make sense to use OAuth?
Typically a mobile app is considered a public client. Unless you're limiting who has access to the mobile app, it can't be considered trusted as someone could mess with the app outside of your control even if you developed it.
Also, the resource credentials grant type is generally not a good idea.
One thing is that the OpenID Connect spec requires authorization code, id token, or a hybrid flow:
Authentication can follow one of three paths: the Authorization Code
Flow (response_type=code), the Implicit Flow (response_type=id_token
token or response_type=id_token), or the Hybrid Flow (using other
Response Type values defined in OAuth 2.0 Multiple Response Type
Encoding Practices [OAuth.Responses]).
Some other reasons:
Why the Resource Owner Password Credentials Grant Type is not Authentication nor Suitable for Modern Applications
The OpenID Connect RFC says you MUST verify the ID token:
When using the Implicit Flow, the contents of the ID Token MUST be validated in the same manner as for the Authorization Code Flow, as defined in Section 3.1.3.7, with the exception of the differences specified in this section.
Although, you may qualify for this exception from 3.1.3.7 if using TLS:
If the ID Token is received via direct communication between the Client and the Token Endpoint (which it is in this flow), the TLS server validation MAY be used to validate the issuer in place of checking the token signature. The Client MUST validate the signature of all other ID Tokens according to JWS [JWS] using the algorithm specified in the JWT alg Header Parameter. The Client MUST use the keys provided by the Issuer.
If you're able to trust the client, and the user/pass check you've implemented, then you should be able to trust that an access token has been granted to an authenticated identity according to the OAuth 2.0 spec.
The access token in OAuth 2.0 also contains scopes and should limit what can be done with that access token. A login without OAuth doesn't necessarily.
It's a good idea to use OAuth to protect the credentials of the resource owner. If you were to use the resource owner credentials grant type, this still provides some benefits as the user could enter the password only when the client doesn't have a valid access token, ie, the user can enter her password once for an access token and validate the user using that instead of entering the password again or storing it somewhere.
Even though this grant type requires direct client access to the
resource owner credentials, the resource owner credentials are used
for a single request and are exchanged for an access token. This
grant type can eliminate the need for the client to store the
resource owner credentials for future use, by exchanging the
credentials with a long-lived access token or refresh token.
OAuth 2.0 RFC6749
1) Do we need to verify the signature of the ID token if the client
only is only interested to get the user information? Also note that
the ID token is coming from the token endpoint via https connection.
YES.
2) Let's forget about the ID token. Can we treat the user has passed
the authentication check (i.e. login success) if the client obtains an
access token from the Auth Server? This flow is very similar to simple
password login without OAuth.
If I understand the premise. Yes..There is no requirement for using the ID Token.
3) The client can access protected APIs with the access token. Without
access token, the client can only invoke some public APIs. Is it
equivalent to what can be done with and without login? It seems the
access token can be treated as "login session cookie".
The access token is a access (like a key) that for the OAuth Client to use that was delegated permissions from the resource owner.
4) There is no 3rd party involvement in my case. Everything (client,
auth server, service API) is developed and owned by the same
organization. Does it still make sense to use OAuth?
Yes. OAuth and OpenID Connect are used by many, many organizations and is a test solution.
You should not try to re-invent the "wheel". Use known trusted libraries for Authentication, Authorization and cryptographic operations. OpenID Connect has some certified Implementations

Why JWT is a stateless authentication?

I am trying to understand how JWT authentication is stateless. In stateful authentication, there will be a session id. Here there is a JWT token which is signed. So the authentication server issues the JWT token, but can I say the validation of the JWT token in subsequent requests are done by the endpoint server (application server) rather than the authentication server. I believe this is possible as JWT is signed with expiry date (and also some other information) and the public certificate of authentication server is available to all endpoint servers.
So the authentication server will be only responsible for issuing the tokens and not validation. The validation will be done by the endpoint server.
Is my understanding correct? Is this how JWT is made stateless? Otherwise, I don't see how it is different from a stateful authentication as both can be implemented using tokens.
In stateful authentication, the centralized server will be responsible for issuing the tokens as well as validation is each request.
JSON Web Tokens (JWT) are referred to as stateless because the authorizing server needs to maintain no state; the token itself is all that is needed to verify a token bearer's authorization.
JWTs are signed using a digital signature algorithm (e.g. RSA) which cannot be forged. Because of this, anyone that trusts the signer's certificate can safely trust that the JWT is authentic. There's no need for a server to consult the token-issuing server to confirm its authenticity.
Notice in this diagram that the Resource Server does not need to check back with the Authorization Server:
Source: https://jwt.io/introduction/
In stateless authentication there is no need to store user information in the session. We can easily use the same token for fetching a secure resource from a domain other than the one we are logged in to.
Refer : https://www.jbspeakr.cc/purpose-jwt-stateless-authentication/

How to validate an OAuth2 access token (JWT) without accessing the auth server

Trying to understand the 2-legged client credentials scheme in OAuth2. Some people state that JWT is great format for Access Token because it is self-contained and resource server doesn't need to verify the token from the authorization server (STS). But how is this done? The only way I see the resource server could itself validate the JWT is by storing a public key on the server, which is used to verify the signature.
When using a JWT as an access token, the Resource Server doesn't need to call out to the Authorization Server to verify it. Indeed the Resource Server will need to store the public key of the Authorization Server to do so. Obtaining that public key is an out-of-band process.
Verification of a JWT consists of checking the signature plus some additional checks on claims embedded in the token e.g. timestamps (iat, exp, nbf) and identifiers (aud).
The advantage of JWT over other forms of signed data/tokens is that JWTS are standardized and flexible wrt. cryptography used by them which makes it possible to use standard libraries to create/verify them instead of having to write custom code.

Should client create their own JWT

Is it safe to allow a third party client to create a valid JWT for our resource API? All the examples I've seen require we provide an authentication server for issuing the JWT to authorized clients.
I think you need understand the difference between resource server (RS) and authorization server (AS).
If you trust the third party client to do the token issuance and validation on your behalf, it is totally fine to delegate the token process to them.
With that said, the flow would be like this:
user-agent access your resource endpoint.
your security chain check if user has authenticated session, if yes, proceed the request.
if not, redirect user to third party authentication endpoint with token.
after successfully authenticate the user, callback to resume the resource access.
if failed, take the user to access denial page.

Why use Client Credentials flow?

I've been looking at using oauth2 client credentials grant to secure my API (all users will be trusted 3rd parties). I'm following the same approach as paypal here: https://developer.paypal.com/docs/integration/direct/paypal-oauth2/
However, I see that HTTP:// basic auth is used to acquire a bearer token. Then the bearer token is used to secure the API calls.
What I don't understand is, if you're going to trust TLS and http: basic auth to retrieve the bearer token - why not just use http: basic auth for the API calls? What is the benefit of using bearer tokens?
What am I missing?
Adding to what Ankit Saroch is saying, going the OAuth way with Tokens may open up other possibilities in the future; say you may want to extend the flow to include User information. By only validating tokens, this means you will probably not need to change the token validation (which is simple) in your service, but rather only the authentication and authorization steps.
But obviously you're right in what you are saying: The Client Credentials OAuth Flow is not more secure than simply using techniques like API Keys or Basic Authentication. All of those rely on the Client being confidential (it can keep its credentials to itself).
The OAuth Spec (https://www.rfc-editor.org/rfc/rfc6749#section-2.1) talks about these Client Types. In total, it's worth reading the spec actually.
As per The OAuth 2.0 Authorization Framework: Bearer Token Usage
The access token provides an abstraction, replacing different
authorization constructs (e.g., username and password, assertion) for
a single token understood by the resource server. This abstraction
enables issuing access tokens valid for a short time period, as well
as removing the resource server's need to understand a wide range of
authentication schemes.
The server that is authorizing the request and giving you the Bearer Token, may be different from the server that actually controls the resources that you are trying to access.
As per the RFC, they have been shown as two different entities. The one giving you the Bearer Token is Authorization Server and the one serving the resources is Resource Server.