I am new to OAuth and OpenId, and after reading multiple pages and information I still do not feel confident at all.
My goal would be to create an iOS Application that communicates with my BE. I need the iOS app to authenticate the user to access their resources.
Reading about OAuth, the solution seems to be straight forward. Just use the Authorization Code Flow with PKCE to make the App have an Access Token. This way I am authorizing my iOS app to access user's data. When the iOS app calls https://example.org/user with the access token, the resource service (my BE server) can get the access token and call the introspection API to know to which user the access token is bound to, and return the correct user data. Since authorization needs authentication to be made in the first place, having the access token would mean that the user is (or at least was) authenticated.
First thing that confuses me: According to the OAuth specs, OAuth is not an authentication protocol, but still the protocol authenticates the user using the user's credentials. Why is OAuth asking the user for credentials, instead of relying on another protocol/flow for user authentication? Such protocol would just acknowledge to OAuth that the authentication was successful.
This first issue made me start reading about Open ID Connect specification and the ID Token. This token would be received by the iOS app. What is the iOS App supposed to do with it? I can already get the user information calling the /user endpoint. How would this ID Token be an advantage?
tldr
Access token (OAuth 2.0) - authorize against OAuth protected
endpoints.
ID Token (OIDC) - authentiation by client application.
Authorization server authentication - It's there to detect
authenticity of end user involved in both protocols (pseudo
authentication from client application perspective)
OAuth is not an authentication protocol, but still the protocol contain a step to authenticate the user using the user's credentials
Correct, OAuth is not an authentication protocol. It is for authorization, which means identifying there are correct access grants to access a protected resource (protected resource ? ex:- An API, A photo stored in a backend).
So why you see end user login dialog ? Well that is the job of authorization server. It authenticate end user to be known by it and then issue the access token to client (client == in simple terms the application which end user uses). So yes there is an authenitcation happening, but this is not applicable to your client application or protected endpoint. One can define this as an pseudo authentication.
OpenID Connect - For authentication of client application
In the original RFC (RFC-6749), OAuth 2.0 was defined as a framework. OpenID Connect was an extension that built on this framework. What it provide ? Well as you found out, it introduce the ID Token. And ID token is issued by authorization server to be consumed by your client application. It contains end user identity information in JWT format. By validating integrity of this token, your client application can authenticate the end user. And access token ? That's there to used against protected endpoint. It doesn't say anything about end user to client.
Related
I am working on the ASP.NET MVC 5 web application. It has only one layer which contains views as well as business logic/operations. Business logic is logically separated from UI but it is not behind a separate web service/API layer.
Now when I use OIDC and OAuth2.0 for my application, there is no separate Resource Server, so to say. Because Client itself has all the Resources I want to have access to.
I am using Authorization Code Flow for authentication & authorization.
Questions:
Does access token have any role in this case? If yes, what?
How am I going to practically use the access token? Since the client itself is the resource server, there is nothing to which I need to send access token to.
I guess you get an ID token which contains all the information you need for authentication of a user. If not, you can use the access token to get the user info. If this is all the information you need, then the access token is not needed anymore. This happens, because OAuth2 is a permission delegation protocol, not an authentication protocol in a first place.
When you have the user info, you can implement between the browser and your ASP.NET backend in any way. You can take a look at the OAuth 2.0 for Browser-Based Apps RFC.
In this case you should use Client Credential flow instead of Authorization Code flow.
In Client Credential flow, your application would send your client id & client secret to Authorization Endpoint directly and asking for access token. Authorization Code is not needed in Client Credential flow. Details as below
An authorization code flow typically need your client redirect
resource owner to authorization endpoint and get a authorization
code from authorization endpoint, client than uses this code to get
access token, at the end of the day client uses access token to
access protected resource.
In Client Crendential flow. your client app is actually the owner of
your resource. So no need to asking for a authorization code. direct
uses its own client credential to get access token from
authorization endpoint and use that access token to access protected
resource(Resource server)
I've began to take interest in the OAuth 2.0 specification and am not sure if what I've understood so far is correct.
OAuth is an authorization protocol while OpenID Connect is an authentication protocol which extends OAuth.
The first deals with authorizing access to a 3rd party resource, by a client application. Example you are building some app and would like to use some other application (which is not yours to own) features (resources).
On the other hand OpenID connect, deals with authorization, authorizing some human entity by verifying his/hers identity to, for example, access a specific resource that only him/her alone has access to. Example you're a banking application and allow users to access their account but first they need to confirm their identity with an Authorization Provider.
So is it safe to say that Authorization is destined to application interaction while Authentication for human interaction ?
Your understanding on OAuth and OpenID Connect is correct. When OAuth was introduced, it define a way to obtain access tokens, which the holding party can used against an endpoint protected by OAuth access tokens. This allowed identity details to be stored in a central location (authorization server aka identity servcer) and that central location to maintain token obtaining process (which include human authentication too).
While access token are used to grant access (authorize), OpenID Connect introduced ID token that get transmitted along with access token. The ID token is there to be consumed by the client application, which is used to authenticate the end user.
Token obtaining require authentication at authorization server. Depending on the token obtaining flow (aka OAuth grant), this authentication will involve the human user. It is also possible to follow a flow which does not involve a human user. Such flow only produce an access token. And OpenID Connect can only be used when human user is involved.
Q : So is it safe to say that Authorization is destined to application interaction while Authentication for human interaction ?
If your application (client) involves and end user, then that user can involved in token obtaining flow. And you can obtain access token as well as ID Token. Then you use ID token for end user authentication. And access token is used to connect with another endpoint.
If your application does not involved an end user (ex:- A service), then you will use OAuth to obtain access token, which used against another endpoint.
Im a bit confused about oauth2 and OIDC.
So supposedly with OIDC we now get the id_token which uniquely identifies the user in the same oauth2 flow.
But my understanding is - oauth 2 came out earlier than OIDC and OIDC support is not universal even at this point.
So how do current APIs that use oauth2 (without OIDC) work?
Let's say there is a mobile app that needs to use some API.
Is the idea that after mobile app get's oauth2 access token -> they always have to hit some endpoint like /me using that access token which will then provide user id information? and thus the api has to track which access tokens have been given to each particular user?
Sry this question comes out like request for some trivia info - but Im really new to oauth2 & OIDC and just trying to understand and make sure im not missing anything....
OAuth 2.0 NOT an Authentication protocol.
OAuth 2.0 is more of a delegation protocol where the Resource Owner delegates certain permissions to a OAuth Client.
OIDC is an Authentication protocol built on top of OAuth 2.0.
OAuth 2.0 should be used where a user (Resource Owner) is delegating permissions to an Application (OAuth Client) to perform some action.
OIDC should be used where an an Application (OAuth Client) needs to some "Level of Assurance" that the user (Resource Owner) is who he says he is.
The Authentication is done by a Third-Party (Authorization Server). The id_token allows the Client to access information about the user that the Authorization Server knows about (and hopefully has performed some verification).
As jwilleke answered it, OAuth 2.0 is for authorization. OpenID Connect (OIDC) is built on OAuth 2.0 adds Authentication layer.
Basically, OAuth 2.0 delegate the client application to access a protected endpoint on-behalf of the resource owner. In simple words, end user authorise the application access a resource/service. In this process, application does not receive any detail about the end user so it cannot authenticate/detect(In OIDC, application receive the id token, which is self-sufficient enough to authenticate the end-user) end user.
Q : Is the idea that after mobile app get's oauth2 access token -> they always have to hit some endpoint like /me using that access token which will then provide user id information? and thus the api has to track which access tokens have been given to each particular user?
From OAuth 2.0 perspective, there is no end user information sharing. But the token issuing identity provider understand the tokens it issued. Internally it can map end user details, permissions and anything it requires to process it. With that, when the API (resource server) receive the access token, it can validate the token. Note that resource server and authorization could be the same or different. And these are implementation specific details. Alternatively one could use token introspection as defined in rfc7662 to detect validity of issues access tokens.
Example scenario
You have mobile app A. And it have the ability to use a service B (protected by Access tokens) which is exposed by service provider G. Assume there is a user Alex who have already registered at SP G so have access to service B and uses app A. And SP G have OAuth 2.0 implemented so service B accepts access tokens issued by SP G.
User Alex use App A and there is a functionality in the App A which need to consume service B. App A require authorisation from Alex to consume service B on-behalf of him/her. In doing so, there will be a user login process and at the end SP G issue access token to App A. Does it convey identity of Alex ? No it does not. But App A can now consume service B using access token it received. Service B fully understand and can validate access tokens issues by SP G. IMO This is OAuth 2.0 in nutshell.
p.s - Substitute known services like Google calendar, Google identity and your android app so that it make more sense.
I have implemented an OAuth2 register workflow (in Java) according to rfc6749
I'm using GitLab as OAuth2 Provider.
After the user granted access to my application for his account, I get an OAuth Token (along with refresh token and other stuff), I am able to make API requests on behalf of the user, so this is working fine.
This way I can get the users e-mail adress which I use to create an internal user.
My questions are:
Is it practice to issue a token that is generated by my application for the user (along with the OAuthToken) or should I just use the token that has been issued by the OAauth Provider? (My App also has local auth with bearer tokens). This token will be used for further API - CLIENT communication (stored in Angular2 local storage as bearer)
How to do login only? When a OAuth User accesses my web service, how do I know that this user is a OAuth User and which OAuth Token belongs to him? How can the user login without providing e-mail or password? (The user has no password) I guess I have to redirect him to the OAuth Provider again, but I don't want my user to grant access everytime he logs in.
Answer 1:
Though you can use the token provided by OAuth provider, you SHOULD NOT use it considering the risk that may arise exposing it to the public.
Instead you should securely save the token provided by OAuth provider into the database and use another token for authentication of further api calls. (you could use JWT)
Answer 2:
There are two types of systems
Which always uses OAuth provider for identifying user. (Ex. Tinder)
Which provides both OAuth Login and Traditional login/signup. (Ex. Quora, Instagram)
If you want your application to follow 2nd approach, you should ask the user to create password for the first time when the user logs in using OAuth provider.
This will allow the user to log into your application by both methods, traditional as well as OAuth
To identify users of your application, you should either use HTTP session or issue your own tokens. Do not use tokens generated by the OAuth2 provider - they are meant to be used just by your backend (in role of an OAuth2 client).
To use an external authentication in your application, you probably want to use OpenID Connect, not a bare OAuth2. OpenID Connect extends OAuth2 and it's meant for authentication instead of the rights delegation. Then you use an implicit flow (instead of authentication code grant) with scope=openid, your frontend app (HTML+JavaScript) gets an ID token signed by the OAuth2 provider. After successful signature verification, your backend can trust that the client is the one described in the ID token (in its "sub" field). Then you can either keep using the ID token or generate your own token.
I am trying to implement OpenId Connect for SSO in one of my projects. However, I am a bit struggling with the case where I would like to validate OpenId JWT token on Resource Server side to make it stateless. If user tries to logout, authorization Server will know about the user logout (Accordingly OpenId Connect Session Management spec). But how should Authorization Server tell Resource Server that the user's token is not valid anymore? It is a case when user after log out out goes to Resource Server with his OpenId token and gets access. That is weird and I could not find any solution across Internet. Please help me to organize stateless security with central logout.
You can use Token Introspection endpoint to determine whether the access token passed is valid or not. The resource server can make a call to OP's introspection endpoint to validate the token before giving access to the resource. In order to effectively validate the token, the resource server should :
Be a registered client with OP and have Same / similar Scope as SPA app (Implicit flow app) to validate the scopes passed to it and
Have access to Introspection endpoint
The are more details in the above linked Spec for further understanding.
P.S. The answer that I wrote earlier has some other relevant references.
you can use jwt bearer flow, where you can pass ID token/Assertion token to OP in order to generate access token.