I use OAuth2.0 of identityserver3 for SSO in company, I cannot understand how does the state parameter prevent the CSRF.
I have copied the attack flow as below:
1.Mallory visits some client's website and starts the process of authorizing that client to access some service provider using OAuth
2.The client asks the service provider for permission to request access on Mallory's behalf, which is granted
3.Mallory is redirected to the service provider's website, where she would normally enter her username/password in order to authorize access
4.Instead, Mallory traps/prevents this request and saves its URL(Callback Url)
5.Now, Mallory somehow gets Alice to visit that URL. If Alice is logged-in to the service provider with her own account, then her credentials will be used to issue an authorization code
6.The authorization code is exchanged for an access token
7.Now Mallory's account on the client is authorized to access Alice's account on the service provider
I can understand step 1 to step 4. But from step 5 I got some confusion. Accordding to my understanding, in step 5 Alice visit the Callback Url when she is logged-in, and then the server just use the authorization code to access the OAuth service provider to get an openid and access token in backend, and then Alice's browser just executing login with Mallory's account and access token.What is the relationship with Mallory's browser?
Could you explain it in detail please? Thank you for taking time to read my word!
I think steps 3 and 4 are not quite right. I've edited your example to show how I think the attack works.
1.Mallory visits some client's website (e.g. https://brilliantphotos.com) and starts the process of authorizing that client to access some service provider using OAuth (e.g. Acebook - as brilliantphotos.com allows its users to post pictures to their Acebook page)
2.brilliantphotos.com redirects Mallory's browser to Acebook's Authorisation Server requesting a redirect back to itself once auth is done.
3.Mallory is redirected to the Authorisation Server, where she enters her Acebook username/password in order to authorize access.
4.After successful login, Mallory traps/prevents the subsequent redirect request and saves its URL(Callback Url with an auth code related to Mallory) e.g.
https://brilliantphotos.com/exchangecodefortoken?code=malloryscode
5.Now, Mallory somehow gets Alice to visit that URL (maybe as a link on a forum post...) note that Alice may already be logged-in to brilliantphotos.com with her own account.
6.Alice clicks the link to brilliantphotos.com and the authorization code is exchanged for an access token (access to naughty Mallory's account). If Alice is logged in then brilliantphotos.com could conceivably associate Alice's account with the newly minted access token.
7.Now if Alice continues to use the brilliantphotos.com website, the client may inadvertently be posting pictures to Mallory's account on the service provider (Acebook).
If a state parameter was maintained by brilliantphotos.com then Mallory's state code would be bound to her browser but not Alice's. Therefore brilliantphotos.com would not be able to correlate the state code with Alice's browser session when Alice clicks on the malicious URL.
Besides iandayman's already great answer, you can also get some inspiration from this blog post, or at least you can take a look into its illustration.
PS: Credit goes to original blog author.
Related
There exists OAuth extension to manage grants called Grant Management for OAuth 2.0.
It says we have to return grant_id at token endpoint and later we can use it in another authorization request.
But imagine a scenario:
The client redirect user to authorization server, receives grant_id
The user logs into another account at authorization server
The client redirects user with grant_id. Now, the user id associated with grant_id is another than id of user currently logged in authorization server.
It could be a big privacy issue if authorization server could have not checked if the user id of logged in user is another than the associated with grant_id.
But what authorization server have to do in this case? Shall return error? Force user to login into valid account? Or maybe ignore requested grant management params?
Specification doesn't say what to do in such a case and I'm really confused.
My understanding of an Oauth2.0 Server is that it grants clients access to resources when the resource owner has granted permission to a client. So say I have a user Bob and he's given permission to two clients (client1, client2) to access his stuff. As part of that Bob logs in 2x. Once like so:
http://10.234.233.23:9081/oauth/authorize?client_id=client1&response_type=code&scope=all
and he gets an auth-code -> FIbSqy
and again like so for the second client
http://10.234.233.23:9081/oauth/authorize?client_id=client2&response_type=code&scope=all
and again he gets a second auth-code -> h4ckJQ
He hands those auth-codes off to app1 and app2 respectively. Then those clients log into the oauth server and exchange those auth-codes for tokens. Then ever after the tokens are used to make calls and get resources.
My question is how the heck do you authenticate two clients at once on the auth server when the auth server appears to cache the first person's credentials and then never lets anyone else login.
Because for me the first client to exchange an auth code for a token...gets tokens and every other sorry client afterwards gets the following error:
I know you can register clients...and I have them all registered with the outh server...but is there also a "login" url that I'm missing that lets them all login at the same time?
OAuth supports state. This is recommended to prevent cross-site request forgery. This state can be used to support multiple logins simultaneously.
http://10.234.233.23:9081/oauth/authorize?client_id=client1&response_type=code&scope=all&state=some-big-random-number-string
I've a site which will hopefully use a third party service for logging in (through use of OAuth2 and OIDC). I understand 90% of the process involved but am failing to get what I see as the final step. I'll describe the steps as I see them here and maybe someone can help me fill in the gaps. In my set up the Resource Server and Authorisation servers are the same machine.
This is the login process as I envisage it.
User comes to my site (let's call it Site A) and clicks login
They're redirected to the authentication site (Site B) where they
input their username / password.
Assuming correct credentials they're then redirected back to Site A with an auth code.
Site A takes this auth code and in a back channel communicates with Site B
again asking to exchange the code for a token.
Site B provides an access token to Site A (not to the end user, to the server)
Site A then communicates with Site B again (Resource and Authentication servers are the same in this scenario) and gets the relevant user detail.
So the user is authenticated and we know what claims they have, however, what I don't get in the above scenario is how Site A knows who I (the end user) am.
I never logged in on Site A so presumably no cookie was set. Basically I've gone to the site, been redirected to another site, logged in there and then am redirected back to Site A but is there a cookie set at that last redirect to identify me?
I've read plenty about this online but haven't found a clear answer.
Also, am I correct in thinking that in authorization code flow that the access token never gets to the user but instead resides on the application server?
If you really want to know who the user is on SiteA, it has to be the user from SiteA's own user database. It makes sense if SiteA is not just a proxy for SiteB's API and has its own users, permissions and functionality.
To figure out who the user is on SiteA you will need to match all your SiteA's users with Auth Server's users.
Part 1. Import your existing users into Auth Server
If you control Auth Server, import all your current users into its user database. Every one of them will have Subject ID (Id on Auth Server side). Copy those IDs back to corresponding users in your SiteA's db: your SiteA's User table will have new column, for example:
userid, user_name, user_last_name, user_auth_id (new column)
if you can't import all your users, it gets complicated. The only way I can think of: you will have to log those users in twice - once into OIDC provider and once in SiteA and then associate SiteA's user with OIDC user.
Part 2. Matching the incoming user to the internal user in SiteA
In successful response from OIDC Server you will get ID Token back. It contains sub claim with Subject ID of the user. When you've got that, you will need to do a lookup in your internal DB and find a corresponding SiteA's user. If you did not find one, create a new user at SiteA (if all existing users had been imported)
Once you know who the user is, log them in to SiteA like you would normally do (give them a cookie for example).
OpenID Connect auth servers provide the userinfo endpoint, which Site A can use for getting info about the user who authorized the access token (or the authorization code). For the auth provider (Site B) to be able to do it, it needs to keep association between a token and its user. So there is no cookie for this purpose.
You are correct about the auth code flow - the access token stays at the backend - there is no need to send it to the frontend / user.
To be able to pair the tokens kept at the SiteA backend with the consequent requests from the browser, you have few options:
You can use a backend session with cookies, which is very easy, because most backend frameworks have a built-in support for it. The cookie is sent automatically with each request and the tokens can be stored in a session object. This solution may be harder to scale - if you need a cluster.
You can create your own session implementation - either by using cookies or by some identifier expected on REST API as the Authorization HTTP header value. The backend session data can be kept in some distributed storage, such as Hazelcast or database. The session identifier can be in form of signed JWT, so you can keep user info in it.
Hi I'm just getting started on the v4 CTP so I can see me posting some basic questions as I get my head around it. I want to create a service provider so I'm looking at the WCF Oauth2
The first thing is when I go to login what is the format of the OpenID for use with the provided database? What is the process for this. I assume I'll get redirected to a screen where I put my password? And that interacts with the database?
Cheers, Chris.
The sample OAuth2 Authorization Server's database merely contains a couple of sample client entries so that the sample client can make requests. It has a users table that is automatically populated by each user who successfully logs in using their OpenID. So to your question regarding the "format of the OpenID" to use, any valid OpenID 1.1/2.0 identifier will work.
The OAuth2 authorization server sample doubles as an OpenID relying party in this respect, but its OpenID functions aren't the meat of the sample -- there are other sample OpenID RP sites that demonstrate more functionality in that respect. But being that OAuth2 auth server and OpenID RP are coupled in this way, the flow is that:
User visits OAuth2 Client site and indicates to the client that it may request access to user's data on the resource server.
Client redirects user to authorization server so the user may grant permission.
Authorization server prompts the user to log in, if not already logged in.
User enters OpenID
Authorization server redirects user to their OpenID Provider to log in using some credential (username/password, infocard, etc.)
OpenID Provider redirects user back to authorization server.
Authorization server sample then asks the user "do you want to share resource [x] with client [y]?" User confirms.
Authorization server records that user authorized client [y] to access [x] so that future requests from that client for that resource may be auto-approved without user intervention.
Authorization server redirects user back to Client with authorization grant.
Client receives the grant along with the user redirect and uses a direct HTTP request to the auth server to exchange that grant for an access token (and possibly a refresh token).
Client then includes the access token in HTTP requests to the resource server to access the user's private data.
I hope that helps.
Background:
MySite.com - my website
ParentSite.com - website of a client
company (which will have OAUth
provider module on it)
MySite Module - a module which I have created which will be installed on ParentSite.com
and which will allow users of
ParentSite to be redirected to MySite (via
OAuth). I have full control over what
I do in this module. I will be displaying links that users will be clicking on and expecting to reach MySite and be fully logged-in.
My understanding of a standard OAuth setup:
Users go to a specific URL on MySite.com for OAuth login into ParentSite.com.
The MySite app retrieves an OAuth "request token" from the ParentSite.
The browser is redirected to the ParentSite.com site, asking to confirm that the MySite App is allowed to see the user's information.
The user confirms. (*)
The browser is redirected to the MySite.com, which now has an OAuth "access token" for the user.
The Client App sends a REST request back to ParentSite.com, using the OAuth access token from step 5 as authentication, requesting the user's identity information (e.g. ParentSite user ID, name, email address).
The ParentSite validates the OAuth access token and returns the user's information to the Client App.
My scenario is slightly different, the differences are:
A. The users are users of ParentSite.com and are at ParentSite.com and need to be seamlessly connected to MySite.com when they click on certain links on "MySite Module"
B. I would like the user-authorization step (step 3 and 4) to be automated, ie, no prompting of the user.
Q1: What do I have to do at "MySite Module" to enable all this? (detailed answer needed please!)
Q2: How can I automate step 3 and 4?
Ok, let me get this straight. Clicking on something in "parentsite" opens something on "mysite", "mysite" then tries to manipulate stuff at "parentsite" and therefore needs to be authorized to do so? If I am wrong, please disregard this answer.
I am also assuming that you have control over parentsite.com - otherwise I can not see a way for you to accomplish what you seem to need.
Part 1.
First of all, mysite needs a consumer key and secret.
Part 2.
Since calls to mysite are issued directly from parentsite, you can issue an access token directly within the parentsite service (you already know which user is logged in). So when accessing mysite.com - simply send it the access token and secret it needs.
Part 3.
Ok, so now mysite.com should have consumer key/secret and access key/secret and should be able to do stuff with parentsite.com.
Keep in mind that this really is outside the oAuth specification, but perfectly doable.