What is the proper Authorization Code OAuth2 flow? - oauth

I'm currently unfamiliar with the OAuth2.0 Authorization Code Flow and I've read many articles about it and currently I still don't know how to properly implement it. So far, what I know about the flow:
User Logs in using OAuth
User is redirected to the authorization server for authorization code
Callback for permission/scope
Redirected to authorization server for access token in exchange for authorization code
Redirect back to the client with the access token
Client uses access token to access resource server.
Right now, what I'm still confused is that where should the login validation come (Login of username - password)? Is it a separate validation before going to OAuth flow and once the user is valid, it should go back to the flow?

I have some resources that explain OAuth 2.0 using Google Sign in as an example. Let me try to rephrase it according to your question.
Let's use the example of a user logging-in to Intercom using "Sign in with Google".
The user presses the button "Sign in with Google". This will redirect to the identity providers /authorize endpoint (could be different for each provider) which go to their login page.
The user is redirected to Google's accounts page. If not already logged-in, the user can enter their Google email/password here.
Google redirects back to Intercom with an authorization_code (for example, it redirects to https://intercom.com/authcallback?code=XYZ...)
Intercom's backend server sends this authorization_code with the client_id and client_secret (from their project in google), and receive an access_token (usually to the /token endpoint)
Intercom can then use the access_token to access the user's profile from Google.
So to answer your question, the user can enter their email/password inside the OAuth provider's page. Keep in mind that OAuth 2.0 doesn't specify how the provider is authenticating the user. This means, that the OAuth provider can authenticate their users in different ways, like email/password, email magic-link, SMS OTP, etc. Your website is just supposed to trust the OAuth provider that they are authenticating the user for you correctly.
Some extra resources that would help you understand OAuth 2.0 more:
How to store the OAuth 2.0 access and refresh token in your front end
Picking the right OAuth 2.0 flow

login validation come (Login of username - password)?
OAuth 2.0 NOT an Authentication protocol
The OAuth 2.0 specification defines a delegation protocol
Any use of username - password is outside of OAuth 2.0 and you should be looking at Open ID Connect which is an authentication protocol built on top of OAuth 2.0.
Best current Practice for Authorization Code flow is to use PKCE on OAuth or OpenID Connect.

The usual solution is to externalise both OAuth 2.0 and Open Id Connect from your code by using a mature security library. When you're new to this type of security there is a learning curve. My resources will give you an idea of how it all fits together:
Code Sample
Tutorial Blog Post
The libraries you integrate depend on the technology stack you are using. The resources above are for a Single Page App and NodeJS API.

Related

how would authentication be done in OAuth2 without OIDC?

I know there is lots of material on this point out there but I still dont quite get it.
I know that OAuth2 is not for authentication and that you need OIDC on top to have authentication.
But still don't quite understand why.
If I look a the implicit flow, one of the steps is that the user authenticates to the authorization server and an access token is then issued.
This is authentication, isn't it?
So why do we still need OIDC and the ID token? Is it because the access token itself is not enough and the JWT makes sure the user can be authenticated later on by the backend services?
And how would you do authentication if you only had OAuth2 and no OIDC?
Disclosure: I work for Ping Identity.
I wrote a blog on why OpenID Connect is useful on top of OAuth 2.0, and I think it would help out here.
https://developer.pingidentity.com/en/blog/posts/2019/oidc-adds-authentication.html
Basically, the OAuth 2.0 framework provides a way for the client to ask the authorization server to go and get authorization from the resource owner.
ie, the client says to the authorization server, "I need to access a protected resource owned by John, can you go ask John to authorize this access." The authorization server can then do it's thing and come back with an access token to the client to access the protected resource.
However, if the client asks, "How do I know it was actually John that provided authorization?" the OAuth 2.0 framework doesn't give a way to answer this.
OpenID Connect provides that extra ID token, in addition to the access token, that the client can check to see if it's John.

Open ID Token vs Oauth Token

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.

OAuth2 Login (Not Authorization)

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.

OAuth 2.0 authorization with my own password

I'm developing an application with OAuth 2 feature. But my case is special. I only want to use my own account to login. Let me take the Facebook as an example to explain the flow of my application:
User start the application
Normally the OAuth will request the user login to his/her own FB account to authorize. But in my application, I want to login to my FB account. Because I know the my own user id and password. Is it a method to login to my account silently?
User is able to post message. In this case, they will post to my FB account.
Is this possible? Do you have any suggestion? Thanks
OAuth 2.0 allows for this type of flow, as defined in the so-called Resource Owner Password Credentials (ROPC) grant. However this flow is less preferred and for backwards compatibility only because it defeats OAuth's primary goal of not having to enter end-user credentials in the client.
FB does not support the ROPC grant so you'll have to go through the regular Authorization Code flow. Once you get a refresh_token through that initial flow, you can use that as a long-lived credential to get new access tokens in the same way that you would use the FB username/password.

Login with password and facebook

I am in the process of designing an app that is supposed to let you login using either a username/password combination or facebook login. We have a custom OAuth server that uses user credentials to authenticate users. Now, the question is how to add facebook into this.
As I see it now, when the user wants to login with facebook, the client does all the work and gets the access token in the end. But how do we let our server know that this access token is a good one (and corresponds to a user in the database)? To me it seems like our OAuth server should be able to handle this as well, and I'm just missing the how.
OAuth supports different scenarios (flows). Client-does-all-the-work is so called "implicit" flow.
In your case it would be better to use authorization-code flow and extend your OAuth server. You put a "Facebook" button on your login page and instruct Facebook to redirect to a new special page on your OAuth server. Delivered authorization code then can be exchanged to the access token inside of your OAuth server and the server may issue its own session and tokens based on this.

Resources