I want to implement OAuth Authorization Code flow.I have a problem with storing state. I'm implementing Auth Server, Resource Servers and the Clients.
What i know is that when the client performs redirect to Auth Server's login form it should send state aswell.
So my Auth Server get 'state' and sends back login html page.
Now after User's credentials will be verified with success, Auth Server should redirect User-Agent to given redirect_uri in the request with 'state' given by the client within request to the login page.
How do my Auth Server know which 'state' should be returned to which Client ? Becouse i have 'state' from Client after first request and then i'm returning html login page. Then User is submitting this form with its credentials and then redirect happens. So how do i store 'state' to match. Where is 'state' between request and credential submit ? How do i store it that later i know it should be returned to particular redirect_uri?
You should return the same state value that you received in the initial authentication request back to the client.
You can for example store the initial state value in a session cookie with each user; by using this technique, you can keep track of the state.
Related
OAuth2(PKCE flow)
A client app makes a call to /authorize endpoint of the authorization server with code_challenge and code_challenge_method. Both code_challenge and code_challenge_method are required in the subsequent requests of the authorization server along with user credentials to generate the authorization code.
I can think of 2 options for how to store code_challenge and code_challenge_method to use in the subsequent calls:
persist the code_challenge and code_challenge_method before redirecting to the login page or user consent page
pass the code_challenge and code_challenge_method to the login page in query parameters, those then will be submitted along with the credentials
As RFC does not talk about this much, which option is better and why, or are there any other options? Please suggest.
Also, are there any best design practices about authorization server endpoints(except /authorize and /token) implementations in OAuth2(PKCE flow)?
According to Add Login Using the Authorization Code Flow with PKCE
There are 2 codes when doing PKCE :
Code verifier, the random string
Code challenger, the hashed string from the code verifier, and his hash method, the code_challenge_method
In the Oauth2 authorization_code flow, a client needs 2 tokens:
authorization token, to request accessToken
accessToken, to access resources
To get the authorization token with PKCE, a client app will have to pass the code challenger & method in the URL parameter, then the user is redirected to login page.
After login, the authorization server redirect user back to the client app, with authorization token in url parameters.
Finally the client app request access token with authorization token, code verifier, client id, and all other parameters.
When the ressources server receive the request for access token, it has to "remember" which code challenge to use to test with the code verifier.
Suppose there are 1000 users authorizing in the same time, there will be 1000 authorizations & code challengers per app client id.
The authorization server should accurately find the right user (authorization & code challenge) along the 1000 users to verify the code & generate access code.
I think this answers your question, storing code challenge after user login, which means pass it to login page (but encrypted, because there is a code challenge methode named plain...)
I don't see how we can link the user & code challenge when the authorization server first receive the authorization request.
RFC 7636 Section 4.4 states (emphasis mine):
Typically, the "code_challenge" and "code_challenge_method" values
are stored in encrypted form in the "code" itself but could
alternatively be stored on the server associated with the code. The
server MUST NOT include the "code_challenge" value in client requests
in a form that other entities can extract.
This rules out your option 2, as the challenge would be available in plain text to the user agent. It does however specify another option to encode this information into the code value, but it seems like this is not what you're looking for.
You're looking for a way to store the challenge while redirecting the user to the login page, before generating the code. In this case you could store the challenge in an encrypted httpOnly cookie in order to maintain a stateless design. A successful login would redirect the user agent back to your /authorize endpoint where you can extract the cookie again and generate the authorization response.
Is the protocol for silently obtaining Access-Token in SPA while a user session in the Authorization Server (Auth0) is still active - Triggers a call to get updated user claims/roles from whichever social connection/database the user authenticated with?
If not, how should I update the silently re-obtained Access-Token from the Authorization Server with the accurate claims/roles?
One can supply prompt=none as a parameter in an authorization request sent a hidden iframe which will result in a new id_token sent back in the authorization response if the SSO session at the Provider is still valid.
I am reviewing OKTA. I have two authorization servers configured, the default one and a custom one. I have a client (web app) that is configured and correctly logging in. I am getting back the expected id_token and access_token. The problem I am running into, is how do I call an api, that is expecting an access token from the second authorization server? How do I request an access token on behalf of the logged in user (default auth server) from the second auth server, without prompting the user to login again? This is all done in .net core mvc application.
In each of your applications you can check for an active Okta session. If found initiate the OIDC AuthN flow.
This is the endpoint on the client you can use to check for an Active Session
https://developer.okta.com/docs/api/resources/sessions#get-current-session
You can use the following authorize URL to get the access token or id token
{{url}}/oauth2/{auth server ID}/v1/authorize?client_id={client id}&response_type=token&response_mode=fragment&scope=openid&nonce=nonce&state=state&redirect_uri={redirect url}
Get the auth server ID from the URL when you see visit the server in the UI.
The above call needs an active session so if you signed the user the first time with 'default' auth server recently. You don't need to sign the user again to get to the token for the second auth server.
I'm trying to use the Hapi's plugin Crumb to implement a solution againts CSRF attacks, but seems that I didn't get the solution flow.
I could simply set a token in each http response as a cookie. And here comes the question, how REST can validate CSRF token, if token issued by client? How REST backend understand what this random string is valid for this request and another random string is not?
It's not possible to generate CSRF token on the client. It should be send from server to client first, and some JS frameworks extract it automatically from the cookie and send it to the server.
The basic idea is that user is supposed to send token along with a cookie and also in the post data. Here is a simple example. If attacker will trick a user to send a particular request to a service, for instance malicious website can have an image with this link src="gmail.com/deleteaccount=true". If user is logged in to gmail. Gmail will think that it was a user who made the request, because cookie send along with request is valid. So, in order to make sure that it was actually a user, gmail also requires a token send with a request data: so instead of gmail.com/deleteaccount=true it needs gmail.com/deleteaccount=true&token=987y23459827345sdfg. Token have to match the one stored in the cookie. So when request is received by a server, it checks if token in the cookie equals to token in the request body. Attacker have no access to user's cookies and don't know the token.
Here is the simplified data flow:
In more details it looks like this:
1) User sends GET request to a server
2) Server sets the cookie with
sessionid, and saving session data with the token
3) server returns HTML with a form containing token in a hidden field.
4) User submits
form, along with a hidden field
5) server compares token from the
submitted form (hidden field) with the token saved in the session storage. If they match, it means that form is submitted by a user.
Here is another grate answer: Why is it common to put CSRF prevention tokens in cookies?
I'm developing a YouTube application that needs to have a User table with the usual data associated with it in the database. I've decided to go the OAuth route for this application and have 2 tables, one of the AccessToken and one of the RequestToken.
I'm not sure what is to be linked up to a User table of some sort, would it be the access token or the request token?
If the token expires would I just lookup which user has that token then update it?
To sign the user out do I just delete the token for the user and clear the token from the session?
EDIT: In other words, I basically want a user to not have to register to my site but to just login via OAuth and have my application create a user entry in the User table so all of my other data can be linked up to that.
There are two parts to this: login and resources.
If you only want to use YouTube for login, you don't need to store the access token at all. When the user comes back from YouTube with the access token, you make one call to get their YouTube id (not sure if YouTube supports an extension parameter with the id in the token response) and discard the access token. If you also want to make other calls to access the user's YouTube data, you need to keep the access token.
A common way to implement this is:
When the user visits your site you set a session cookie with some random string we call state.
The user clicks on 'Sign In with YouTube'
You go and get a request token from YouTube, then either store it in some local cache (can be a database, redis, memory if this is a small scale app, memcache, etc.) or encrypt it and store it in another cookie on the client. When you make the request token call, include a 'state' parameter in the callback with the value set as cookie in #1. This is a critical security defense against CSRF. Also, your redirection endpoint should use SSL.
You redirect the user to YouTube with the request token (and optionally the encrypted request token secret cookie)
The user logs into YouTube, approves the application, then gets redirected back
You check that the user coming back to the redirection endpoint matches the user you originally sent over by comparing the value of the incoming state parameter with that of the session cookie from the user.
Fetch the request token secret from local cache or by decrypting the token secret cookie used earlier (which ever method you decided to use) and request an access token
Using the access token, make a YouTube API call to get the user information
Lookup in your database to see if you already have a user with that YouTube id. If you do, this is just a login, and if not, this is a new user registration so create a new record for them in your users table.