I am using this library: https://github.com/manjeshpv/node-oauth2-server-implementation
From my understanding of Oauth2:
1)Generate a clientid and clientSecret
2)User use clientId and clientSecret to get a bearerToken
3)Authorisation server returns accessToken to users if valid clientId and clientSecret combination
4)User then use the accessToken to run http post/get api calls (within their scope)
In the POSTMAN examples given in the GITHUB, we have
I noticed Password Grant, Refresh Token ,Client Credential Grant and Authorisation Grant points to the same POST request with the difference in the body.
and the Authorise sample web service, which I assume is that user would have to click in order for the authorisation server to return an access code for user to call scope specific API urls, but somehow access code is needed too, which I'm confused.
and If I use Client Credential Grant (which I assume is to return an AccessToken using my clientId and clientSecret), then what's the point of the authorise webservice?
What would be the right flow for this library and webservices example?
Would really appreciate help in this, thanks!
and the Authorise sample web service, which I assume is that user
would have to click in order for the authorisation server to return an
access code for user to call scope specific API urls, but somehow
access code is needed too, which I'm confused.
Your terminology is a bit confused. Here is a probably most popular OAuth flow:
Developer (you) registers OAuth client, receives clientid and clientSecret
User opens some url like oauth.com/authorize, is shown a dialog asking to give some rights to developer's application. (Here clientId is used, but clientSecret is not required)
If user agrees, authorization code is sent to developer's application (to redirect_uri defined at step 1). This code is short-term and cannot be used to access user's data.
Developer's application makes POST request to OAuth server with authorization code, clientId and clientSecret and gets authorization token in exchange. This token can be used to access user's data.
and If I use Client Credential Grant (which I assume is to return an
AccessToken using my clientId and clientSecret), then what's the point of the authorise webservice?
Token got by ClientCredentials grant identifies client, but not user. So I guess it is useless in your case.
Related
I'm using cognito to authenticate to node-js using amazon-cognito-identity-js I logged in and it returns me an access_token, id_token and refresh_token but none of them work when I'm using the open id scope with authorization code grant.
I don't know if I need to call another service or do another process to get access at the gateway
but when I generate a token using client_credentials flow the api gateway works
If I understood correctly, the scopes you are setting are OAuth 2.0 scopes and require using the OAuth 2.0 endpoints (e.g. the hosted UI, or an external IdP federation). Your code seems to be using the non OAuth 2.0 flow (e.g. I assume InitiateAuth with SRP). If you decode the JWT I believe you will see it has only the aws.cognito.signin.user.admin scope.
For using custom scopes you will need to
send the access token (not the id token)
use token you got from the token endpoint (e.g. using the hosted UI or federation) - they will contain the scopes you set in the screenshot
For using the open_id scope, same as above but send the id token, not the access token, and remove the custom OAuth scopes in API Gateway (if you put them it will expect an access token)
p.s. custom scopes work great with the client credentials flow, but less with the authorization code flow if it doesn't have a client secret.
Lastly I recommend you take a look at AWS Amplify as it will handle a lot of that for you behind the scenes as well as include security features such as PKCE out of the box.
Relevant github issue: https://github.com/aws-amplify/amplify-js/issues/3732
I am using Open ID Connect and requesting tokens from Azure Active Directory. I am using the authorization code flow, so I am receiving both the id_token and the access_token. I am using .NET Core.
My configuration of Open Id Connect is as follows:
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
Notice the Save Tokens set to true
When the user is logged in, I am able to retrieve both the tokens as follows:
string accessToken = await HttpContext.GetTokenAsync("access_token");
string idToken = await HttpContext.GetTokenAsync("id_token");
My question is, where these tokens are actually being saved, and how can I configure how these tokens are being saved?
I also heard that in the authorization code flow, the identity provider will return the authorization code, and the server would then use that code to request the tokens. However, I am not doing any of that programmatically and I am still able to retrieve the tokens. Is this something handled automatically with Open Id Connect?
Where these tokens are actually being saved?
As the OpenID Connect protocol diagram architecture describe, When a new session is started, a new cookie is returned to control this session. This "sesion cookie" is created based on "ID Token" and as long as this cookie is valid, user will be considered as authenticated. As you are using, OpenID Connect (OIDC), it create the cookie and save token there. you could refer this docs
How can I configure how these tokens?
If you want to configure your token mechanism Microsoft provides library fro that. You can use ADAL or MSAL for your own configuration.
Is this something handled automatically with Open Id Connect?
Thought its has some background mechanism but you have to use authentication library to handle on your application code. You could refer official docs
For more details you could refer flowing docs
Authentication implementation
Authentication Libraries
Code sample
response_type is set to code indicating that you are using the Authorization Code Flow.
When you use OIDC auth code flow along with clientid and clientsecret to get token, the work process is as below:
1.The user clicks Login within the regular web application.
2.Auth0's SDK redirects the user to the Auth0 Authorization Server (/authorize endpoint).
3.Your Auth0 Authorization Server redirects the user to the login and authorization prompt.
4.The user authenticates using one of the configured login options and may see a consent page listing the permissions Auth0 will give to the regular web application.
5.Your Auth0 Authorization Server redirects the user back to the application with an authorization code.
6.Auth0's SDK sends this code to the Auth0 Authorization Server (/oauth/token endpoint) along with the application's Client ID and Client Secret.
7.Your Auth0 Authorization Server verifies the code, Client ID, and Client Secret.
8.Your Auth0 Authorization Server responds with an ID Token and Access Token (and optionally, a Refresh Token).
Let's say you are developing a client side JavaScript SPA app (Angular), a backend API for this app (ASP.NET Core in my case) and you use an identity provider that implements Open ID Connect protocol (I'm using IdentityServer4).
Apparently the recommended way for securing the app is to use the OIDC implicit flow between the JavaScript app and the identity provider and if successful the JavaScript app gets an id token and an access token.
Now according to this documentation the JavaScript app is supposed to pass the access token in the headers whenever it calls the API. And I'm not sure what purpose does the id token serve in this case (besides customizing the UI in your JavaScript app)?
But this is the confusing part: The documentation also says you should never use the access token for authentication. But that is the token that my API receives in the request headers, how can it authenticate the user then? If my API receives Post(newRecord), and the API needs to internally fix some audit information on newRecord (i.e newRecord.CreatedBy = CurrentUsername), how can it do that without authenticating the caller??
I think I'm missing a piece of the puzzle. Please any help is deeply appreciated.
Short answer/suggestion
Use Access Token to access API endpoints. From API endpoints, you must use token introspection endpoint to validate token validity (active state) as well as obtain subject who authenticated at authorization server. IdentityServer provide support for this. Documentation is available from here.
Explanation
ID token is intended to be used by receiving client. It will allow your client to authenticate the end user and provide user specific customizations. This is the whole purpose of OpenID Connect (OIDC). On the other hand OAuth 2.0 provide an authorization framework. It replaces user credentials with access tokens, thus improving API access security (compared to basic authentication and storing user credentials everywhere). Hence OIDC is built on top of OAuth 2.0, you get both ID Token and Access token with OIDC flow.
But as you have figured out (and mentioned before), ID token is intended for client. There are could be exceptional cases where ID token get passed between client and a server. This is mainly when both are controlled by same party. But the access token is the key to access API endpoints, correctly.
Access tokens can be an opaque string or JWT. When it's a JWT, API can read and understand the token (self-contained). When it's opaque, only way to validate token at API endpoint is to use token introspection endpoint. If API can validate token validity, then it could grant access (authorize) request. Furthermore, if user details (subject) are available (through JWT or as introspection response), then user specific checks can be executed. This further extends to token scope values. But at the end of the day, you are authorizing the API request and not authenticating the user at API endpoint. That's the highlight. Hope things are clear now.!
Why do we need first contact the Oath Auth endpoint to get an auth code, and then once we have received the auth code we need to contact the Oauth Auth endpoint again to get the access token so that we can call a webservice?
Why not just return the access token in the first step, after the user has signed in successfully?
Also, how does the webservice (API) then verify that the access token is legit?
Why do we need first contact the Oath Auth endpoint to get an auth code, and then once we have received the auth code we need to contact the Oauth Auth endpoint again to get the access token so that we can call a webservice?
So the web service (or Relying Party) never sees the user's credentials.
And because of how this flow works, the user also cannot see the application's credentials.
User also can't get the access token to use it themselves, though that actually would not matter that much.. Implicit Grant Flow actually does what you want, allowing you to get an access token directly from the authorization endpoint. But that is mainly for Single Page Apps, for which that is the easiest option.
Authorization Code Grant flow allows the app to use a stronger authentication via a client secret or certificate.
This is called an OAuth dance by the way :)
Why not just return the access token in the first step, after the user has signed in successfully?
See my mention above about Implicit Grant flow.
Also, how does the webservice (API) then verify that the access token is legit?
By checking the digital signature. Azure AD (and B2C) publish public keys for the key pairs they use for signing at a well known endpoint.
The authentication pieces in an app must check the JWT signature is valid by the defined public key.
When I first heard of OAuth was in ASP.NET Web API applications and I've used it as means of authorizing users to access resources on a RESTful API. By the time I felt I was using it right, but right now I think I got the idea wrong and this is the subject of this question.
At the time, I used OAuth in the following way: on the API there was a token endpoint to issue tokens. I created a login page in a SPA and posted the username and password to the token endpoint with a grant type password and the token that came back I started sending with each request.
When the request had the Authorization: Bearer [token] header with a token issued with some username on the login page I understood the request was being done "with the user logged in" and so I could authorize access to resources.
Studying OAuth deeper my conclusion is that my usage of OAuth was completely mistaken.
My understanding now is that OAuth is just for authorizing applications and not users. In that case when we make a request with the Authorization: Bearer [token] header we are saying identifiying to the resource server that the client making the request has been authorized to access the resource, but we are not saying anything about the user?
In that case, with OAuth we just can say what resources client applications can access but we have no information to decide whether the user is allowed or not to the resource? Because of that my initial usage is truly wrong right?
OAuth 2.0 can be used for authorizing a client (an application) to call an API. This authorization is done via an authorization grant.
The grant is given by the resource owner in the case of authorization code, implicit and resource owner password grant through authentication of the user with the authorization server and clicking accept on a consent screen.
The first two grant flows are interactive and require an agent that understands HTTP (redirection) responses.
Most authorization servers also support the client credentials grant. In this case, there's no user involved and a pre-registered client (application) uses its own client-id and secret to authenticate with the authorization server.
Which grant flow to use depends on the type of client you use and who owns the resource the client needs to access. I describe the differences in my answer here.