Is it okay to use an OAuth2 authorization code as proof of a successful login? - flutter

I have a database with emails and passwords, and a Flutter app that lets those users log into the app by providing their email and password (the old fashioned way).
Now, some of those users are part of an organization that has a separate website where they use Microsoft/Office 365 accounts to sign in. Of course they want to be able to log into my app using their Office 365 accounts as well, instead of having to remember and type a different password in the app than they normally use on their organizations website.
So I've been looking at their website, which uses Microsoft Azure as a the backend. From their current login page I could find the tenantID, clientID, redirectURL and scope. From this I am able to get an authorization code back from the login.microsoftonline.com authorization endpoint. However, as my app is not registered in the organizations Azure account, I don't have a clientSecret so I can't call the token endpoint and get an idToken.
I'm using a WebView to display the login to their organizations website, so I can grab the authorization code from the redirect URL when they are redirected.
So my question is if I can use the authorization code directly to verify that the user has successfully signed in using their Office 365 account? All I need to know is that the user has an account at the organization, and that they could provide a valid email and password to login.
If they are redirected to the redirect URL with an autorization code, it means that they successfully logged in. Then I could consider them logged in to my app as well, based on the email provided to the Office 365 authorization endpoint. Because if they couldn't log in to their Office 365 they wouldn't get an authorization code, right?

No, the authorization code only has meaning to the identity provider, in this case Azure AD. It doesn't prove anything to your app.
What you could do is try response_type=code+id_token in the authorization URL.
If ID tokens have been configured as returnable from the authorization endpoint (this is done in the app registration configuration), you will get back a signed id token that you can verify.

Related

What does it mean to "redirect with token" for single sign on?

(Background: I am trying to use my website hosted on wix as a simple identity provider so my members can access a separate sveltekit app I am creating--without logging in again--on a separate server because I do not think I can create the app on the wix platform. Basically I just need the user id, but I would like to also ensure they are in fact authenticated on my Wix hosted site before granting access).
In multiple pages explaining single sign on, it is explained that when my browser requests a protected resource from a web server, the server can (if it is configured to do so) verify my identity via a separate identity provider. This is done via a redirect to the identify provider. If I am not authenticated by the identify provider, I am asked to authenticate (by entering username and password, or whatever).
Once I am authenticated (by logging in or by verifying the presence of a valid session id on the identify provider's server from a prior login), the identify provider then "redirects with token" or a "token can be passed to the original domain by a redirect" according to these web sites I have encountered.
But what does it mean to "redirect with token"? This conflicts with other reading I have done which points out that redirects cannot have authentication or other headers or data associated with them.
How does it come to pass that (1) the web server I made my original request from gets my token from the identify provider while at the same time (2) returning my requested resource to my browser instead of back to the identity provider's server?
"Redirect with token" is a common method used in single sign-on (SSO) systems to authenticate users. In this method, when a user tries to access a protected resource on a server, the server redirects the user's browser to the SSO login page, along with a token that identifies the resource being accessed and the server that is requesting authentication.
The user then enters their login credentials on the SSO login page. If the credentials are correct, the SSO system authenticates the user and sends them back to the original server, along with a token that indicates that the user has been authenticated. The server checks the token to confirm that the user has been authenticated, and if the token is valid, the user is granted access to the protected resource.
Redirecting with a token is a secure and efficient way to authenticate users across multiple servers, as it allows the servers to rely on the SSO system to authenticate users and eliminates the need for each server to store and manage its own set of login credentials.

JWT Token nested in the "idp_access_token" Claim of the B2C token

My project is a MVC Core 3.1 web application.
The autentication is based on the Microsoft.identity.web template to sign-in users in Azure AD B2C.
You can find the samples here: https://github.com/AzureAD/microsoft-identity-web/wiki#samples
Users can register/login as standard users on B2C or login with the corporate account (azure AD, so an openID Connect Identity Provider).
When Users signs in with the corporate account, I get a JWT token with a claim named "idp_access_token" which contains the access_token from Azure AD. It contains some claims I need for the application (for some reasons I can't even see the emailAddress/unique_name in the B2C token so I need to get it from here...).
But I'm not sure how (and where) I'm supposed to deal with this token and how to access the claims inside it. Can I map them in the claimPrincipal? Because I would like to use the email as the "User.identity.name".
Should I write a service (transient?) and Inject it where I need it?
Sounds like you are using a feature you don’t actually need. Usually the embedded IdP access token is used to call the services that the IdP hosts. For example, a user logs in with Facebook and your app wants to call the Facebook API to post to their Facebook wall.
You as the app developer should not inspect or use the token for your own self, as you cannot trust it. If you want data from that token, then perform the relevant claims mappings in your B2C policy/user flow, as B2C does validate the token and can trust it. You cannot. Services provided by the IdP will verify it, so also can trust it.

Facebook OAuth security using passport-facebook

I am currently using a client-side React component to have a user login to Facebook via OAuth in my application. On the server-side, I use the npm package passport-facebook-token to validate the authenticity of the accessToken after a successful client-side login.
One practice I do not see often is in addition to asking Facebook if the accessToken is valid, shouldn't the server also check if the email provided by the client's payload matches the e-mail coming back from Facebook? Allow me to use defined client/server technologies to illustrate my question:
1) User uses React component on the client to authenticate with Facebook.
2) React component successfully authenticates with Facebook and fires an HTTP request to the server with an access token and the user's email.
3) The server, running Node.JS and passport-facebook, now needs to verify the authenticity of the access token directly from Facebook. Facebook does not care for an e-mail. It will just verify the access token.
4) Facebook returns a response to Node.js confirming the authenticity of the access token. The response also contains other metadata about the user, including their email and other profile data.
My question is, should Node.js take the email that's also coming back from Facebook's access token verification payload, and verify that it is what came back from the React client? Would this not prevent someone from brute-forcing an accessToken and require them to not only have an accessToken but also know who the accessToken belongs to? This could prevent a user from submitting a bunch of HTTP POST requests to the Node.js server attempting different access tokens. They would not only have to guess an access token assigned to the application's clientID, but also know the e-mail it belongs to. Is this an over-engineered approach?
Really the best way I can think of to make your OAuth accessToken and 'code' value less prone to brute-forcing is using a Cryptographic Number Generator to create a 128-bit length string of random data and encoding it with base 64 to use as your code. It's extremely unlikely that it would be guessed by a computer or by someone redirecting to and from the authorization endpoint and the redirect-uri with query parameters.
Another method of fortification is limiting the rate of authorizations by IP address (which you can do instead of email through Node.js) but that is usually not a problem for most well-equipped hackers. I highly advise the first method for creating a more secure service.
Your approach to validate the email as well as the token is a bit superfluous because Facebook's opaque user access tokens are inherently tied to email.
From Facebook
An access token is an opaque string that identifies a user, app, or Page
"opaque" is defined by Auth0 here
Opaque Access Tokens are tokens in a proprietary format that typically contain some identifier to information in a server’s persistent storage
In your case, the identifier is the user's email, and the server belongs to Facebook.
I will elaborate further. Here is your step by step with some edits:
User uses React component on the client to authenticate with Facebook, inputting both their email and password directly to Facebook. React component gets the token from Facebook on login success.
React component successfully authenticates with Facebook and fires an HTTP request to the server with an access token and the user's email.
The server, running Node.JS and passport-facebook, now needs to verify the authenticity of the access token directly from Facebook. Facebook does not care for an e-mail. It will just verify the access token because the access token is already tied to the email.
Facebook returns a response to Node.js confirming the authenticity of the access token. The response also contains other metadata about the user, including their email and other profile data.
This is Facebook's bug bounty program. If their OAuth was really as cracked as to require a second email validation, it would have been patched almost immediately by this incentive.

Api request to login/create/link user via Identity Provider

I need to be able to do the operations that keycloak do when using identity provider: login/logout/create account/link account, via api, not via html.
I am unable to find in your documentation how can i do these actions, all the documentation is based on html and a series of redirect, by using keycloak and its theme.
This is not compatible with a single page application, or ios/android native application.
Examples:
Get token and refresh token by using Identity Provider brokering (google/facebook), for existing/already linked accounts, when i already have the google/facebook token.
Required steps:
I get the google or facebook token, outside of keycloak.
I need to post this token into identity provider broker.
I need to receive from this response, the authorization and refresh tokens, just like i do a login with user/pass by using route ".../protocol/openid-connect/token"
Create a new account with the user received from Identity Provider, when i already have the google/facebook token.
Required steps:
I get the google or facebook token, outside of keycloak.
I need to post this token into identity provider broker.
I receive that there is no such user, and if i want to create the user.
I post that i want to create the new account.
I need to receive from this response, the authorization and refresh tokens, just like i do a login with user/pass by using route ".../protocol/openid-connect/token"
Link an existing account, with the google/facebook account received by Identity Provider.
Required steps:
I get the google or facebook token, outside of keycloak.
I need to post this token into identity provider broker.
I receive the information that the same account exist, and if i want to link the account.
I post that i want to link the account.
I need to receive from this response, the authorization and refresh tokens, just like i do a login with user/pass by using route ".../protocol/openid-connect/token"
I tried to do hacks and ajax calls, instead of html request, but in the end it does not resolve my problem, because i don't know what happened: it logged in? it created an account? it requires to link account?

Login with oauth validate token

I want to create an app that will authenticate with my server using oauth.
My question is how will this work?
My client side will communicate using HTTPS with Facebook and get an Access Token. Then it should send it to my server side to authenticate? My server should save the token in the db? How it can validate the token?
how will this work. ?
When the client needs authorization to access some information about the user, the browser (user agent) redirects the resource owner to the OAuth authorization server. There, the user is faced with an authentication dialog (this dialog is not shown if the user is already authenticated), after which he or she is presented an authorization dialog explaining the permissions that the client is requesting, the information that it needs to access or the actions that it needs to do on his or her behalf.
Access Token should send it to my server side to authenticate? or server should save the token in the db?
From what you describe I'd suggest to use a server-side login flow.
-so that the token is already on your server, and doesn't need to be passed from the client. If you're using non-encrypted connections, this could be a security risk.
(after a user successfully signs in, send the user's ID token to your server using HTTPS. Then, on the server, verify the integrity of the ID token and retrieve the user's ID from the sub claim of the ID token. You can use user IDs transmitted in this way to safely identity the currently signed-in user on the backend.)
-See
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2#login
How to validate token ?
you can follow this link , you will get your step by step solution for an app.
Facebook access token server-side validation for iPhone app