I am writing unit test for controllers in an asp.net core web application, it uses Identity framework for authentication. I was able to create an authenticated HttpClient with valid bearer token. But when the client tried to GetAsync from an endpoint that is policy protected (e.g. RequireRole("Admin")), it always fails with error 500, but if I make that endpoint [AllowAnonymous], it will work. I've tried using SignInManager to sign in first, thinking that will provide the context user, still the same. So, how to use GetAsync to access a policy protected endpoint in unit test?
Related
I'm creating new app client in cognito user pool with some custom scopes. One of this scopes is predefined and one are created during creation of app client.
CreateUserPoolClientResponse response = client.createUserPoolClient(
CreateUserPoolClientRequest.builder()
.clientName(clientName)
.userPoolId(awsCognitoProperties.getUserPoolId())
.preventUserExistenceErrors(PreventUserExistenceErrorTypes.ENABLED)
.allowedOAuthFlows(OAuthFlowType.CLIENT_CREDENTIALS)
.supportedIdentityProviders(COGNITO_IDENTITY_PROVIDER)
.allowedOAuthFlowsUserPoolClient(true)
.generateSecret(true)
.allowedOAuthScopes(awsCognitoProperties.getPartnerScope(), organizationPathScope)
.build()
)
After app client creation I'm using https://???.auth.us-east-2.amazoncognito.com/oauth2/token POST endpoint in order to get access_token for this app client. When testing manually access token has all scopes in token. But in automated tests we sometimes receive response token with only one custom scope. But in cognito this app client has all custom scopes and triggering POST token endpoint manually after tests returns token with all scopes.
My question is how is it even possible? And how can I prevent this from happening?
In Angular/.net core 3.0 app I am using Azure AD implicit grant flow. The Web API uses authorisation and allows access based on roles (e.g. SuperAdmin, Admin and User roles etc). I need to write automated integration test for the Webapi (I can use a seperate client app too for testing). Any ideas which will be the appropriate grant flow for testing. I have read about ROPC flow (Resource ownder password credentails) flow and its not recommended to be used. I can't use client credentails flow as this wont work with Authorisation. I will appreicate any links or examples.
1.You should send a login request first(To enable the implicit grant flow, select the tokens you would like to be issued by the authorization endpoint…):
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?client_id={your client id}&response_type=id_token&redirect_uri=http://localhost:8080/login/oauth2/code/azure&scope=openid&response_mode=fragment&state=12345&nonce=678910
2.Getting access tokens silently in the background:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?client_id={your client id}&response_type=token&redirect_uri=http://localhost:8080/login/oauth2/code/azure&scope=https://graph.microsoft.com/user.read&response_mode=fragment&state=12345&nonce=678910&prompt=none&login_hint={your-username}
3.You can also refer to the following documents, hope to help you:
https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-angular
Just if it helps someone, I did not find an alternate to get an access token to call the webapi which uses role based authorization (i.e. allow access to only users in certain AD groups) for my integration tests. So created few test users in the relevant AD groups and used resource owner password credential flow to get the access tokens and called the web api
I have a Django Rest API with JWT authentication which is the backend for a Angular frontend. There are many clients who use the service with our frontend. Now some enterprise clients wanted to integrate the APIs from their system's backend. I don't want to remove JWT from current APIs. I am planning to create new APIs in the same backend with OAuth token for those users.
I wonder what is the best way to implement OAuth for this scenario.
I am thinking Client Credentials grant type is the best way.
Question1: Am I right that client credentials is the right approach ?
For those enterprise users, it is sufficient they get just access token through the UI interface so that they can access all our APIs.
But here the problem is one additional step of getting the Client ID and Client Secret first and using that to get Access Token.
Question 2: What is the use of client ID and client secret ?
Question3: Should my backend hide the process of generating Client ID and Client secret and just give Access token (or) give them Client ID and Client Secret and ask then to generate access token ?
Question 4: If I am giving them Access Token without client id and secret, is that fine to have infinite expiry time? and
TLDR; How to implement OAuth when the resource server and auth servers are same ?
There are 4 grant types in oAuth2 which is meant for different scenarios.
client credential : the consumer (app) make calls to back-end using the bearer token created using apikey(or clientId) and secret only. Mostly used for anonymous calls where generic information is retrieved.
Resource owner password credential (ROPC) : the consumer (app) make calls using the bearer token created using apikey, secret, username and password. Mostly used when you(your authorization server) already know the users(user database is handled in your own system).
Authorization code : the consumer (app) make calls using the bearer token created using an authorization code. The authorization code is provided by a 3rd party (which actually has/manages the logged in user data) and the created authorization code linked to the logged in user. Google and Facebook log in for various sites is a typical example. Facebook/Google gives an authorization code for those websites and they exchange that code for a token.
Implicit grant : Mix of password credential and authorization code. Instead of authorization code, you get a bearer token from the 3rd party authorization server.
Question1: Am I right that client credentials is the right approach ?
I think you can use CC if there is no user level logics in your backend. If userlevel involved, may be ROPC is a better choice
Question 2: What is the use of client ID and client secret ?
Client ID and Client Secret is very similar to username and password in an application level, which is used to obtain bearer token.
Question3: Should my backend hide the process of generating Client ID and Client secret and just give Access token (or) give them Client ID and Client Secret and ask then to generate access token ?
If you are implementing oAuth2, your consumer should create the access token. But looking at your use case, may be even a simple hash of userId+timestamp is sufficient. ;)
Question1: Am I right that client credentials is the right approach ?
Yes. Providing the new APIs do not need to be called in the context of an end user.
Question 2: What is the use of client ID and client secret ?
The client ID allows the auth server to identify the application
requesting the token (it's often carried through to the access token
too, allowing the API to identify the calling application).
The client Secret means the auth server can trust that the client is
genuinely who he says he is as only he should have the private client
secret for his public client ID.
It's effectively a username and password in this scenario.
Question3: Should my backend hide the process of generating Client ID
and Client secret and just give Access token (or) give them Client ID
and Client Secret and ask then to generate access token ?
Your Auth server should issue the client credentials to the application once and the application should provide those credentials every time they wish to obtain a token via the client credentials grant type.
authorization code grant, or implicit grant might be more suitable for this scenario. The first one allows you to add an authentication step before the tokens are returned to the users (might be useful if you want to integrate your JWT authentication to this as well) and the second one is mainly used for single-page applications, and does not include an intermediate authentication step. This one would be useful if you want to improve efficiency.
client_id and client_secret are given to you when you register a client application in your identity provider(authorization server). This client application does not mean an application or an API belonging to your clients, but your own application to which you plan to incorporate OAuth(and OIDC). These two parameters are useful when making the requests to authorization in order to obtain tokens. The server uses those values to determine whether the request is made by a valid application. Only you have access to those values as you will be the one who's registering the application with the server.
I think this question is answered in the previous section.
I think it would be better if you go through this before doing any implementation. It provides most of the basic knowledge you should have before implementing an OAuth system. I hope this answer was useful to you.
For some reason, Cognito authorizer gets ignored when I test invoke the method (It works with Postman and any client requests though). I pass the idToken on the Header Authorization so I can use $context.authorizer.claims.sub as my uuid on request transformation, but to no avail.
Right now the test invoke ignores any pre-integration steps, including authorization and throttle/quota check by API Key. We'd like to support a full end-to-end test invoke in the future, but for now you'll have to rely on end-to-end testing via the deployed API.
I'm going to make a REST web service with many resource servers (implemented in different programming languages) and one authorization server.
My question is about token validation in the resource servers. Let's say that a resource server cannot connect to the database and check the token info there.
I have read this thread: OAuth v2 communication between authentication and resource server
And I like the idea to make an API in the authorization server, which will be responsible to "resolve" tokens. For example: https://oauth.example.tdl/tokeninfo?token=tokentovalidate
So my question: Should the /tokeninfo resource be "public"? I mean everyone who knows this endpoint will be able to validate tokens..
Wouldn't it be better to make this "private"? I mean https://oauth.example.tdl/tokeninfo?access_token=valid_token&token=tokentovalidate
But then my resource server will have to authorize itself before validating tokens.. too many requests, I think..
If you know more strategies to validate tokens between resource server and authorization server - tell me, because I'm pretty new to OAuth.
Should the token verification API be public?
In terms of authentication, if should of course be an authenticated API, and the access token that you use to call it is the access token you want to verify. RFC 6750 explains how to do that. Typically, the token is sent in the Authorization header, or as a Uri query parameter.
Alternatively, for more security, you require the client id and client secret to secure the call, either by passing them as parameters, either by obtaining an access token for the client using the Client Credentials Grant.
Be careful what information you return from the API. You should only return information that does not require a specific scope that has to be authorized by the resource owner.
For a real life example, see the Google implementation or the implementation from The Identity Hub. For the Facebook implementation, see the section "Confirming identity" on Manually Build a Login Flow.