ASP.NET Web API 2 Bearer Token Authentication and Resources Authorization - asp.net-web-api

When we build ASP.NET Web API endpoints, we can protect them using [Authorize] attribute and we can use bearer token to authenticate the request and call the endpoint.
My question is about authorization and how we can better grant access to resources once the authentication was successful.
For example if there is an endpoint api/contracts/details and want to restrict access to this for specific people, I am talking about SQL table fields (object properties) or even the whole table. How can this be achieved?
I have a feeling that roles is not the best option here. Any advice?
or
After user registers, he can generate a client_id and client_secret that he must present when requesting the bearer token. I can add the client_id as claim within the token.
In the database I have tables like this:
User (user details)
Client (client_id, client_secret ... etc)
RefreshToken (refresh_token, protected ticket)
I can create another table called Access where I specify all the allowed enpoints (Client Table -> Access Table on to many relation)
Access Table:
api/user
api/devices
api/products
Then I can create a message handler and inspect all the incoming requests. Decode the bearer token, extract the client_id and query the Access table for the allowed endpoints. If the incoming request matches the allowed endpoints then let it pass otherwise reject it.
This should work I guess?

You are best using the roles Attribute, but you will need to create a TokenValidationHandler. Check this excellent answer here

Related

How to store the user uuid and role after authentication in spring security JWT

Hello I want to store the userUUID and role extracted from the JWT for all database queries.
Right now Im passing the useruuid and role as request param for each request.
Thanks
You should store these in the JWT payload itself.
Parse JWT and verify signature if present, on each request and then use them accordingly.
These details should never come from user input or a place where user can modify them.

Oracle ORDS get sessions roles

I googled about this question several days but I couldn't find good resources for my question.
I wanna get the list of roles assigned to ORDS_PUBLIC_USER after a client authorized with the auth2 method (with client_id and secret_key) to call services. how do that? and my other question is how to get which client_id(authorized) and calling services now?
thanks in advance
When a new OAuth token is requested, a row is added to the table ORDS_METADATA.SEC_SESSIONS with that token's information.
In the definition of your REST API, you should be able to get the OAuth token using UTL_HTTP.GET_HEADER and look up that token's information in the table. The STATE column of ORDS_METADATA.SEC_SESSIONS contains JSON that has information about what that token has access to which includes the roles that this token has access to.
You can then use the USERID column of the ORDS_METADATA.SEC_SESSIONS table to match to the CLIENT_ID column of the ORDS_METADATA.OAUTH_CLIENTS or USER_ORDS_CLIENTS table/view to find the OAuth client that the token is associated with.

Does Passport utilize guards not to authenticate users but to validate access tokens on routes where these tokens are required?

I'm a little bit confused by the documentation. It's said:
Passport includes an authentication guard that will validate access
tokens on incoming requests. Once you have configured the api guard to
use the passport driver, you only need to specify the auth:api
middleware on any routes that require a valid access token.
So it means that Passport utilizes guards not to authenticate users but to validate access tokens on routes where these tokens are required. Did I get that right?
In this case, validating the access token is authenticating the user. To understand why this is the case, let's walk through a simplified authentication flow using JWTs (let's ignore oAuth2 for a bit).
The user is logging in on the website. This triggers a POST /login request, with the username and the password in the request body.
The backend validates the users credentials. If the credentials are valid, it will issue a JWT, which will act as an access token. The JWT payload will contain some data that allows the backend to identify a user, e. g. the user id. The JWT then is signed with a secret that only the backend knows.
The backend will return the access token to the client, who has to include the access token in any subsequent requests to the server. Usually, the client will provide the token in the Authorization header.
When handling the next request from the client, the backend will extract the access token from the Authorization header and check its signature. If the signature is valid, the backend can be sure that the token data has not been manipulated, e. g. by changing the user id on the access token. With a valid signature, the backend can extract the user id from the tokens payload and set the User model for that specific id as authenticated. With an invalid signature, the backend will probably return something like 401 Unauthorized.

Understanding the authorization part of JWT and session

So i read about how authentication is done using JWT, where we basically verify if the token is valid using a private key (assuming RSA is the algortihm). And if the token is valid, then the user is considered authenticated. And I also read about session authentication where we check if the user supplied session id (through cookie), exist in the session store (assuming mysql / redis is used to store session). If it exist, then the user is considered authenticated.
But how do we use JWT and session for authorization ? Lets consider an action such as GET invoice , whereby a user can only view the invoice that he owns.
If we consider the user is already authenticated,
how do we check if the user is authorized if we are using JWT?
And how do we do it for session ?
You are probably confusing the things. One of the benefits using JWT is to avoid maintaining sessions which is big bottle neck in scaling.
JWT (Json Web Token) carry all the information that would require it to get authenticated, you don't need to maintain the session. Every single HTTP request to server will carry JWT that would contain necessary user claims including the signature. On server you will validate the signature to verify if the token is valid or not. You can verify the token without maintaining any session and there are number of ways to do it.
Since JWT is essentially a Json object (Header, Body , Signature) , you can put in claims (emails, roles, profile etc) in JWT body. Once you verify the token , you can extract the claims including any roles and check if user is authorized to access the resource.
You must look into Open ID Connect and Tokens here

AWS Cognito: Add custom claim/attribute to JWT access token

My app creates a custom attribute "userType" for each new signed-up user. Now I would like this "userType" claim/attribute to be added to the JWT access token whenever the user signs in or the token gets refreshed.
Is there an option to tell cognito to add my custom claim/attribute to the JWT access token? (Without a pre token generation Lambda)
Custom attributes are not available in Cognito access token. Currently it is not possible to inject additional claims in Access Token using Pre Token Generation Lambda Trigger as well. PreToken Generation Lambda Trigger allows you to customize identity token(Id Token) claims only.
You can use ID token to get the token with custom attributes.
Access tokens are not intended to carry information about the user. They simply allow access to certain defined server resources.
You can pass an ID Token around different components of your client, and these components can use the ID Token to confirm that the user is authenticated and also to retrieve information about them.
How to retrieve Id token using amazon cognito identity js
cognitoUser.authenticateUser(authenticationDetails,{
onSuccess: function(result) {
var accessToken = result.getIdToken().getJwtToken();
console.log('accessToken is: ' + accessToken);
},
onFailure: function(err) {
alert(err.message || JSON.stringify(err));
},
});
I have the same problem when I want to create several microservice. There isn't a way I can customize an access token, but only an identity token. However, I use client credentials in the machine-to-machine which needs access token. So, in no way I can customize my token. At last, I decide to add such info(like user type) in the event header. It's not a very secure way compared to customize a token, but there isn't any other easy way to do it right now. Otherwise, I have to rewrite the authorizer in Cognito. Like rewriting a customize authorizer and it's very painful.
I have the same issue with Cognito; exist other tools like "PingFederate"Auth-server of Ping identity and Auth0 Auth-server; I know that the requirement isn't part of the standard, but these applications were my alternatives to fix this issue
The responses suggesting to use the ID Token for authorization in your backend systems are bad security practice. ID Tokens are for determining that the user is in fact logged in and the identity of that user. This is something that should be performed in your frontend. Access Tokens on the other hand are for determining that a request (to your backend) is authorized. ID Tokens do not have the same security controls against spoofing that Access Tokens have (see this blog from Auth0: https://auth0.com/blog/id-token-access-token-what-is-the-difference/).
Instead, I recommend that your backend accept an Access Token as a Bearer token via the Authorization HTTP header. Your backend then calls the corresponding /userinfo endpoint (see: https://openid.net/specs/openid-connect-core-1_0.html#UserInfo) on the authorization server that issued the Access Token, passing such said Access Token to that endpoint. This endpoint will return all of the ID Token information and claims, which you can then use to make authorization decisions in your code.

Resources