I'm trying to wrap my head around OpenID and OAuth.
From what I understand, OpenID only says that you are a user of the OpenID provider.
So if I log into a site using an OpenID, all it will return is "yes, this person is a user of X site."
If I want to retrieve a users email address, I would need an authorization as well, which is where OAuth comes in.
All that being said, does this imply that if an OpenID username is an email address, there is no way to retrieve that information without OAuth as well?
Here's a good post about OpenID vs OAuth.
From what I understand, OpenID only says that you are a user of the
OpenID provider. So if I log into a site using an OpenID, all it will
return is "yes, this person is a user of X site."
It depends on who you're using as an OpenID provider and whether they support Attribute Exchange - which allow a relay party to ask for additional attributes about a user (e.g. their email). Here's a SO question asking about Google/Yahoo supported Attribute Exchange values.
All that being said, does this imply that if an OpenID username is an
email address, there is no way to retrieve that information without
OAuth as well?
Again, it depends on who you're using OpenID/Oauth (and possibly which version of each protocol too). OpenID providers don't necessarily have to use emails as usernames, and it's possible for a provider to provide both email in their OpenID and OAuth implmentations. For example Google allows retrieval of email address via OAuth2 in addition to providing email in it's OpenID Attribute Exchange.
Related
I am confused about the use of OAuth 2.0 as an Authorization method and OpenID Connect as an Authentication method.
Based on my knowledge OAuth 2.0 is only an Authorization method. In other words, this is the process to request an ACCESS_TOKEN and RECEIVE this ACCESS_TOKEN, like depicted in the image below in yellow ellipse: (simplified)
Before an OAuth 2.0 Client retrieves an ACCESS_TOKEN from an Authorization Server this Server should verify if the User allows it and this is an Authentication Process that OAuth 2.0 does not care about.
When OpenID Connect is included in the mix it allows for an Authentication Method as well, but in my knowledge OpenID Connect just adds a "Claim" in the JWT Token that holds information about user that is using the service, like: email, name and others.
My questions are:
Why not ignore OpenID Connect and just add more "claims" in OAuth
2.0 to get information about users?
Is my description of the flows correct?
OpenID Connect does not merely "add a claim in JWT Token" but:
it introduces a completely new token (id_token) with radically different
semantics than the OAuth 2.0 access_token and a standardized format that is understood by the Client as opposed to the access_token which is opaque to the Client
it "twists" the role of the Client, now becoming the "audience" (or: intended recipient) of a token (i.e. the id_token) whilst the audience of the access_token is still a remote entity (aka. Resource Server) and the Client is only the "presenter" of the latter
The 2nd item is the primary source of confusion between OAuth 2.0 and OpenID Connect.
I don't know if your method will work or not but you're totally free to roll your own authentication. After all, that's what Facebook, GitHub and many others did by customizing oauth2. There ended up being so many oauth2 "authentication" methods that it was never plug and play if you wanted to change your provider. I believe that's why OpenID connect was introduced--a common way of connecting and reasoning about authentication while building on the established oauth2 pattern for authorization. Use OpenID connect or don't...but if you don't you'll be reinventing the wheel.
#sdoxee answers explains thing correctly. But I am adding bit more information for OP's understanding.
These days many identity providers (eg:- Azure AD) issue JWT based access tokens. These JWT access tokens do contain claims about end user as well as JWT related validation details (eg:- Token expiration). Here is the link for Azure AD OAuth 2 success response which highlights access token to be a JWT. Also, see JWT claims to see how they explain the claims. Samples are given below,
family_name : User’s last name or surname. The application can display this value.
given_name : User’s first name. The application can display this value.
One could think of building authentication on claims present in access token, but this is not sticking with protocol. And mostly claims and user information will be implementer specific. Also, by protocol definition, these two tokens (id and access) have two different audiences.
ID token is for client, for validation and for authentication.
Access token is for OAuth 2 protected endpoint.
Again, as #sdoxee highlight, use the correct protocol at correct place. Having claims in access token does not necessarily mean you should use them for authentication.
I'm trying to authenticate my user on my site using StackExchange OAuth API.
Everything works fine when the user signs up for the first time. At this point, I get the "access token", which I save in my DB.
But the next time the user signs in, access token value is actually different to the previous one. Is it supposed to be like this?
If then, how do I check for existing users who already have signed up using StackExchange?
I can get the user's information by giving a specific site name (e.g. 'stackoverflow'). But what if I don't have that information and I need to check that the user has already signed in via StackExchange?
Is there a "user" information that I can get given an accessToken?
The StackExchange OAuth implementation is not meant to authenticate users to 3rd party applications but instead it is about authorizing those 3rd party applications to get access to the StackExchange API.
The access token that you get is not a token that represents a currently logged-in user, it represents the permission to access the API on behalf of the user gave it to your application. This is the classical confusion about the scope of OAuth 2.0 which is discussed in detail here: http://oauth.net/articles/authentication/.
In summary: you can't use OAuth or the StackExchange access token to authenticate users.
StackExchange does support the OpenID protocol to facilitate the purpose that you are looking for, see https://openid.stackexchange.com/. The downside of that is that OpenID is a deprecated protocol, superseded by OpenID Connect. OpenID Connect is an authentication protocol that is actually built on top of OAuth 2.0, but is not yet supported by StackExchange.
I could connect to the Yahoo OAuth from my website.
But I don't know how to access just the email and username of the end user.
Just like what Stack Overflow does when allowing logging in using Yahoo.
Which Yahoo OAuth Permissions(Scopes) does that?
AFAIK, Stackoverflow uses OpenID for the login, not OAuth.
To get the email and name of the user from the OpenID Identity Provider (Yahoo in this case), there are two possible mechanisms:
Simple Registration
Attribute Exchange
By looking at the redirection URL, it seems that, with Yahoo at least, Stackoverflow uses Attribute Exchange and requests these attributes:
http://schema.openid.net/namePerson
http://schema.openid.net/contact/email
http://axschema.org/namePerson
http://axschema.org/contact/email
I'd like to allow my users to login to my website using my login system, or FB Connect or Google Login. I wouldn't want to use big libraries (like dotnetOpenAuth) for only those 2 options - So how should I accomplish this?
Additional question - how should I bind the FB/Google user to my inner user system? I'd like to allow to login using both of them (I could for example login using FB and then login with Google, and still be bound to the same user).
I'm using ASP.NET MVC 2
Thanks!
If you don't like to use big libraries like DotnetOpenAuth you will have to manually implement the OpenID protocol. Here are the specifications you will need to conform to.
This being said, I would recommend you using an existing library. DotnetOpenAuth is the reference library for .NET.
Also a small remark: OpenId and OAuth are different standards and are designed to achieve different things: OpenId is for authentication while OAuth is for authorization.
As far as identifying the same user which could log from different OpenID providers is concerned you will need something to identify them. For example with DotnetOpenAuth when creating an authentication request to the OpenID provider you could require the FullName and the Email:
using (var openid = new OpenIdRelyingParty())
{
var request = openid.CreateRequest(Identifier.Parse(openid_identifier));
request.AddExtension(new ClaimsRequest
{
BirthDate = DemandLevel.NoRequest,
Email = DemandLevel.Require,
FullName = DemandLevel.Require
});
}
and use this information to identify the user within your internal database.
So here's the idea:
You create an internal database table which will contain your site users. At the beginning this table is empty.
A user comes to your site and wishes to use it. He is not yet authenticated so you ask him for his credentials. You provide him the ability to choose his OpenId provider and prepare an authentication request and redirect him to his provider for authentication.
The user authenticates with his provider and is redirected back to your site. At this moment you know his claimed identity and you add the user to your users table. Now the user can always come back to your site and login.
You could provide the possibility to your authenticated users to add another OpenId provider (just like StackOverflow does). The important idea is that the user needs to already be authenticated to your site in order to do this. So he could enter his alternative OpenId provider and get redirected to this provider for authentication. Once he authenticates he is redirected back to your site and because he was already authenticated to your site you could add to the users table his alternative OpenId provider.
The controller action which will handle the redirect from the OpenId provider should check whether the user is already authenticated to your site and if not authenticate him using FormsAuthentication.GetAuthCookie and passing the claimed identity. If the claimed identity doesn't exist in your internal users table you need to add it. If the user is already authenticated to your site it means that he is adding an alternative OpenId provider to his profile, so you would update your users table and add the new provider to it.
I have implemented Google openid authentication for my web application (ruby on rails) , now once authenticated how am i suppose to get the status of that particular user ? like if the user which has been authenticated is a domain admin or not ? i have googled it a bit and came up with Google provisioning ApI and ClientLogin authentication process.... but in case of Clientlogin authentication one has to provide username#domain.com plus the password in the function...
In all i want to know, is their a way to know that a person authenticated by Openid is a domain owner or not ??
According to the open-id specs these are the attributes you can retrieve from your open-id provider (Ex: Google).
http://www.axschema.org/types/