Single-sign-on authentication vs authorization - authentication

I'm implementing Facebook and Google SSO on my website using custom workflow (redirect urls, parsing on server side etc. - no javascript) and I got to the point I have access_token, token_type and expires_in and from Google also id_token and I am confused what to do next to authenticate the user.
I read a little about authorization vs authentication, and that Facebook and Google SSO is OAuth2 which provides authorization, but not authentication, from which I understand that this way my web application is authorized to do something on behalf of the user, but I cannot be sure the user is the one who I think he is? My main source is this: OAuth Authorization vs Authentication
So, my question is, what should I do to be able to can consider the user logged in.
Thank you

In your case google (and facebook) is authenticators. This services just tells your application that user who try to login to your system is the one who he wants to appear.
Assume you differentiate users by unique email.
Your application flow should be next:
The user try to login to application using google Application do all redirection google flow stuff and gives you tokens
Application need to store this tokens for future use
Application check if this user's email presented in database
If email is presented and google returns tokens (google authenticate your user successfully) you can login user in your app
If email isn't presented in database but google authenticate user successfully you can store this user (with email) to your database - sign it up - this is new user in your system
Same flow with Facebook. Surely you can extend this logic to be more your application specific.

SSO and OAuth are different. OAuth is authorization protocol.
You are dealing Google and Facebook oauth.
OAuth
In case of oauth, after successful authentication(google/facebook) you will get access token. You can use token for maintaining the user session.
With this token user is authorized, Now you should check whether the user is present in your database, if yes then authenticate the user and redirect to your application.
SSO
SSO is user authentication service. There are way to implementing SSO like kerberos SSO, ADFS SSO.

We should never use OAuth2 access token for authentication.
For details, please refer
https://oauth.net/articles/authentication/
The OpenIDConnect, built on top of OAuth2, can be used for authentication.
Google supports OpenIDConnect
https://developers.google.com/identity/protocols/OpenIDConnect
The basic idea is Google will issue the client app (your application) a ID Token after the user has login his Google account. You can then extract user information (e.g. email, unique user id) from this ID token and proceed your login flow.

Related

Who generates JWT when using Google OpenID Connect authnentication for my ASP.NET Core Web API app?

I am building an ASP.NET Core 6 Web API application for mobile clients (and maybe later SPA JS app). The application should have sign-in with Google option. I also want to add my own app's custom sign up and sign in options that would also be based on JWT authentication and not cookie.
I understand that for my custom sign in flow my app will generated JWT that will be sent to the client.
But I have few questions how that works when user signs-in with its Google account:
who's responsibility is to generate the JWT when user signs-in with its Google account? Is that responsibility of Google or mine application? I don't want Google to return JWT to the client in the cookie.
Then when client is authenticated with Google, and sends requests to my application, how can my application validate JWT token it gets?
When user signs in with Google for the first time, should I automatically register that user in my application (I am using Identity framework) by taking claim values (email) from the JWT? What is the general practice here?
I am trying to understand these processes and flows so sample code is not necessary (but I do welcome it).
Ad.1. Normally, in a larger system, you would have an authorization server (AS) that would handle user authentication and the issuance of tokens. Your clients would contact only the AS, and the AS will be able to provide the user with different forms of authentication: e.g., through your website's password or through Google. The AS is the single point of issuing tokens to your clients. It can issue tokens regardless of the authentication method used. So it then doesn't matter whether the user authenticated with Google or a password, the client will still get the same access token.
Ad.2. When the AS issues token to your client, then you don't have any problems validating that token. The client doesn't care if the user authenticated with Google or not, it's not relevant in this case.
If you decide to skip using an AS and let the client receive tokens directly from Google, then you can still verify them. An ID token is a JWT and can be easily validated with a JWT library using verification keys provided by Google. Access tokens returned by Google are opaque tokens (If I remember correctly), and you need to check whether Google exposes an endpoint to verify them.
Ad.3. That is the general practice. When the user authenticates with Google and you notice that you don't have that user's data in your system, then you take the information from Google's ID token and create a user entry in your system.

OAuth and authentication

according to here (https://oauth.net/articles/authentication/) and many other things I have come across. OAuth is not meant to handle end user authentication. Reading through the article above and others while searching provides so much information at once from so many angles that it is hard to see through it all. ok...
Does this mean that...
A) The protocol itself is not intended to handle authentication, so therefore, OAuth client apps should inspect "who" can authorize users according to the OAuth providers?
If ONLY the user can authorize third party apps, then isn't the fact of receiving authorization from the OAuth provider in itself proof of authentication? (if this is the case, then can OAuth access tokens from places like Google and Facebook be trusted as authentications?)
B) OAuth client apps cannot trust authenticating users with OAuth, so therefore must provide another sound authentication mechanism alongside it?
If this is the case, then every site that I have clicked "Login With [provider]" (and no other complementary authentication scheme) has got authentication wrong?
It seems to me that if only trusted and specific OAuth providers are used, then this flow could infer authentication
App requests login with trusted providers
User is directed to provider to authorize (ONLY user can authorize)
App then requests and receives token from provider, and adds user to the app database if necessary.
Token is put into secure cookie or JWT and returned to the user to be presented on subsequent visits.
The purpose of OAuth2 access token is to delegate some access rights (scopes) from a user to a client application. So the application redirects the user to an authentication provider (OAuth2 server), which authenticates the user and asks the user (consent step) whether he/she wants to delegate some access rights (the scopes requested by the application) to the application.
If a client application receives an access token, it can get its meta data at the OAuth2 introspection endpoint - such as username of the user (resource owner). So this way, the OAuth2 can be used for authentication. But the main purpose of access tokens is to delegate some rights. For example if a third party application wants to save its data to a user's Google Drive, it needs an access token issued by Google with scopes that allow it to access Google Drive.
If you want to use OAuth2 only for authentication in your client application (to get identity of a user), you can use OpenId Connect (OAuth2 extension) and its ID token, which is in JWT format and contains information about the user that was authenticated the authentication provider. This is better suited for the "Login With ..." functionality.

Identity Server3 Authentication for both Mobile and Web Application

I need to implement an authentication mechanism with JWT tokens for an mvc web application and a mobile application as well. Users will be able to register to our database and authenticate by using credentials (from signup) or use facebook single sign on. Both applications will use web API for data exchange with JWT token. I am thinking of using Identity Server 3 for that using Resource Owner Flow and i have some questions on that:
1) User will login from mobile application and will get a jwt token. Mobile application will verify it's validity and will refresh when needed. In order for mobile application to have user always logged in should i store refresh_token on device??? Is it secure?
2) I cannot understand how am i going to handle facebook authentication and get jwt token from identity server. Should i first get users email from facebook profile data and then what???
Thank you
1- You can store refresh token in database( identity server provide a token stor)
also you can use third party library to store tokens in device securely.
2-To use the 3rd party logins you need to do the redirect style to the IdSvr login page. Using resource owner password flow means you miss out on all the features in the token service like SSO, 2fa and federated authentication.

Twitter API Authentication Flow Misunderstanding

I don't quite understand the api flow for twitter on a per-user basis for API transactions.
Here's my understanding of the user transaction flow:
1./ User signs into our web application.
2./ User authenticates with twitter and then the API sends the user back to a callback destination with a provided oauth_token and oauth_token_secret.
3./ We store the oauth information into a database.
4./ Now we have there access tokens and can send tweets on their behalf without needing them to log into the application again.
HOWEVER, this is not working correctly. When I try to supply the oauth token information, i'm getting invalid or expired token. OK so instead i supply the oauth token provided to me with the user oauth tokens given by the owner of the app and it works.
I think I'm mishandling the authentication process.
I'm reading here at the authentication docs.
Can anyone help me understand how i get my app to handle status updates on a per user level?
Thanks.
Ok. However I read for twitter there is no expiration
This is the actual transaction flow your application will take in order to use Twitter:
Register your application to Twitter to obtain an OAuth consumer_key and consumer_secret. This is for Twitter to identify the application that your user will authorize to access it's account.
When the user wishes to Tweet or access their Twitter resources through your app, The OAuth handshake process will redirect to Twitter, with the application's consumer_key so that the user will authenticate on Twitter directly. Once user authentication is successful, Twitter will provide your application with an access_token.
That's essentially what happens, except that Twitter uses OAuth 1 protocol so the handshake is more lengthier.
Access Tokens do expire for security reasons. It's like when you login to a system, the session is active for a period. When they do expire, you will have to request for an access token again.
I don't know if that explains your question.

Server side authorization with OAuth

is there a way to ask for an OAuth authorization without redirecting the user to the service and then back again to my app?
In detail, I'm creating a web service that need access to the Facebook Graph API, that requires the OAuth 2.0 authentication. Is that possible?
Thanks
The authorization request has to happen for an authenticated (by the OAuth provider, not you) account, and for security reasons the authentication has to be a direct interaction between the end user and the OAuth provider.
Of course, the provider might decide the user is already authenticated properly (there is a fresh auth ticket in a provider-specific cookie for example) and skip the authentication sequence, but there is no way for you to force it to take your word that the user on whose behalf you are requesting the authorization indeed is an authenticated user of the OAuth provider.