IdentityServer4: How to show external providers consent screen? - oauth-2.0

Just recently starting using IdentityServer4 (IS4) playing around with samples and so on.
I have a setup where run IS4 (using the included sample UI MVC) configured with Google as an external provider. I also have an API setup, as well as a client (MVC web app). When authenticating, and the user clicks "Google" in the "External Login" section, he/she is redirected to Google as expected. However, after supplying the username and password, I expected to the see Google consent screen, but instead I am redirected back to the consent screen in IS4. Why is that? Should the end user not give consent that his/her Google profile information is being accessed, on a page which clearly is from Google (i.e. HTTPS and Googles certificate)?
I acknowledge that since I am also requiring consent from the user to access my API I might end up with 2 consent screens (one for profile info from Google, and one for API access from my own IS4 configuration), but if I did not have an API in my setup and simply wanted to use IS4 in a federated setup to provide ID tokens, I would not have a need for the consent of my own API and thus would expect only to see the consent screen from my external providers (e.g. Google, Facebook, Twitter, etc.).
I have my external provider configured like this:
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.ClientId = "<my client id>";
options.ClientSecret = "<my client secret>";
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
});
Could someone please enlighten me :-)
Thanks

From Google' help:
To set up your project's consent screen and request verification:
Go to the Google API Console OAuth consent screen page.
Add required information like a product name and support email address.
Click Add Scope.
On the dialog that appears, select the scopes your project uses. Sensitive scopes display a lock icon next to the API name.
To select scopes for registration, you need to enable the API, like Drive or Gmail, from APIs & Services > API Library.
You must select all scopes used by the project.
When you're finished adding details to the OAuth consent screen, click Submit for verification.
A Verification required window displays.
Add scopes justification, a contact email address, and any other information that can help the team with verification, then click Submit.
Note: The consent screen
settings within the console are set at the project level, so the
information that you specify on the Consent screen page applies across
the entire project.
So, what you need is to disable consent for your client in IdSrv and enable it in Google.
Additionally, as described in this answer,
By design, the consent screen is not shown in the scenario with account selection and profile/email scopes only requested..., since the account selection UI already shows the email and profile (name/picture) information that will be shared with the app.
As added by #Mike Wilcox:
When including a sensitive/restricted scope, if not verified for the scopes added, you will see a not verified screen during consent oauth flow. You can pass through by clicking advanced - > go to [app_name] (unsafe)
There is a playground: https://developers.google.com/oauthplayground/ where you can test this out.Click on the settings icon in the top right and then check the "Use your own OAuth Credentials" box to then enter your app creds. You can add scopes and test out there.

You don't have control when you redirect to external idp since it is a delegated authentication. I don't know how Google have implemented their OAuth flows but the following might be reasons as to why consent screen is not shown:
You are not requesting any scopes that require user consent
The user already gave consent to access to his/her info to your client (you should be able to check this in Google account pages)
Your client is configured to bypass consent screens (this is possible in IDS4 by setting RequireConsent flag to false, but I would doubt you can do this in Google as a 3rd party OAuth client)

Related

Questions to OAuth consent screen - how to edit+support email+verification

Some questions to OAuth Consent Screen:
Is any data that I input while configuring OAuth Consent Screen editable? For example if I decide to change my app's name, can I edit that?
Does the OAuth Consent screen need to be submitted/verified/published in order to use it to test features like achievements or leaderboards?
When choosing the support email, can I choose it from the list if I add that email to the project, or do I need to be logged in with that email and do the whole process from that account?
Is any data that I input while configuring OAuth Consent Screen editable? For example if I decide to change my app's name, can I edit that?
Yes you can edit the consent screen on google cloud console for the project. The app will need to be verified again if you change things like name, description, or any of the URLS like privacy and home page.
Does the OAuth Consent screen need to be submitted/verified/published in order to use it to test features like achievements or leaderboards?
Not sure on this one. My guess would be no if your just testing something it doesn't need to be verified until you are in production.
When choosing the support email, can I choose it from the list if I add that email to the project, or do I need to be logged in with that email and do the whole process from that account?
oauth-2.0.
You need to create a google user with that email address. then you can add that user to your project and set them as the support email. They need to have access to the project you cant just add anyone.

Freshdesk OAuth SSO: Freshdesk Login Page Doesn't Ping My Auth Page?

I'm trying to connect to Freshdesk using OAuth 2.0, for single sign-on from my app. My app is serving as it's own OAuth identity provider. I've set up my Authorization url on Freshdesk -- let's call it https://www.myWebApp.com/auth:
So now for testing purposes I go to the URL that Freshdesk support provided for a user to initiate the single sign-on process:
https://myWebApp.freshdesk.com/login/normal
...and I see a nice sso-style login screen:
I enter a correct email and password for one of my site users and click "Login".
Now in the Chrome network tab, I would expect to see Freshdesk trying to ping my Authorization URL. But I don't. I see this:
When loaded, my auth page (https://myWebApp.com/auth) pings my server, which issues a console.log() message, and my server logs show no such console log message -- so Freshdesk doesn't seem to be pinging my auth page at all.
What is keeping Freshdesk from pinging my auth page as it should?
There is probably a fair bit here that you have in place already but I am just adding it in for completeness.
Logged into the backend and on the security page for contacts
https://stackoverflow.myfreshworks.com/security/contacts
[stackoverflow == your site :) ]
you will have to create a Custom Policy if you don't have one in place already (this is different to the one for Agents)
And for that configure your SSO with Oauth 2.0
Then , if you have at least one SSO configured your login (at https://stackoverflow.freshdesk.com/support/login ) should look like this:
Where (1) now appears. That will be the link to ping your server via the urls you set up for the SSO:
If you only have one SSO set up for your contacts that link (1) should complete the sign-in process directly and then you should end up logged into Freshdesk as the specific contact.
If you had two SSO options set up; for example:
..when you clicked the link (1) on the https://stackoverflow.freshdesk.com/support/login page, you should then be redirected to a page with those two options:
The url for that page is something like (parameters will be different for you):
https://stackoverflow.myfreshworks.com/login
?redirect_uri=https://stackoverflow.freshdesk.com/freshid/customer_authorize_callback
&client_id=14416083630394368&slug=6117145232763
I am imagining you could use that as a direct link to the portal on your main site.
If you only have one SSO option set up you should be able to navigate directly to the link as above and then see :
which is probably what you are aiming for.
I changed the name of that button (Sign in with contacts SSO) just to be sure I was using the right one and to differentiate from the login for agents. You can change the text under the Advanced Options when configuring the SSO:
Hope this helps you along the way - if you have any other questions on this post them as comments.

Google OAuth - How to check that user has already allowed access to my application

Short description:
If a user has already granted my application OAuth access to their google profile, I want to spare them of having to press "sign in using google" button every time they land on my home page and log them in automatically.
If user has not granted access yet, I want to present them with sign in options page with "sign in using google" button.
Long description:
I am implementing Google OAuth flow as described on this link:
Using OAuth 2.0 for Web Server Applications
Just for the clarity, the flow in question is as follows:
present (client side) user with "sign in using google" button
after user presses the button, redirect them to google's OAuth 2.0 server, where they allow/deny my application to access their google profile
if user allows access, google redirects them back to my application
my application (server side) uses acquired grant to get access token
my application (server side) access user's profile using acquired access token
I want to achieve the following:
If user has already allowed my application access to their google profile before (either on current computer or some other), I want them to have an impression of being signed in to my application (using google) immediately after they navigate to my application's URL. Without having to click anything.
This is at first glance not a problem. To achieve this, I would automate steps 1 and 2 of the flow described above. User would be redirected to google oauth server automatically - without having to press "sign in using google" button - right after they navigates to application's URL. Google in turn immediately redirects user back to my application with a valid grant (again without requiring any input from the user). The rest remains the same. User would have an impression of being logged in immediately .
This approach has a problem though. If user goes to my page for the first time (not having granted my application access before), they would also be redirected to google OAuth page. But since they haven't granted access yet, and didn't press any sing in button, they would and end up staring at google oauth server page confused having no clue, what is going on.
Is there some API, by which I can detect that user has not yet granted access to my app (and I should present him with sing in button first)?
Please, if your solution would involve some API calls, point me to a HTTP/REST API, as I don't use (and do not want use) any higher level OAuth library.
Thanks.
Add "prompt=none" parameter to your initial OAuth redirect. This way google will not block if user has not logged in or has not granted your app the permissions.
See Chapter 3.1.2.1 of http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
Short summary of other possible "prompt" values:
none - will not prompt anything, redirects back with error "login_required" or "interaction_required" if silent login is not possible.
login - force the login prompt, even when user is logged-in.
consent - force the consent prompt, even if user has provided consent in the past.
select_account - present account selection prompt.

How to force account login for a single account user with Google's OAuth 2.0?

Sometimes when a user logins into a site with Google's OAuth 2.0 they choose the wrong account to login with. Normally this isn't a problem if the user has more than one account registered with the browser, google will automatically show the user select screen:
But if a user has only one account and is logged in, this screen is skipped. Instead I need Google's sign in panel to always appear, so that I can be sure the user has the option to try and enter the correct account. I tried using approval_prompt = "force", but that forces the acceptance of permissions rather than simply showing the login page.
How can I force Google's OAuth 2.0 to always show the login screen?
(and never automatically skip it)
Add the parameter prompt=select_account to your authorization request.
This will cause the account chooser to always be shown, even if the user is only logged in to one account. Users will be able to select from their accounts, or add a new one.
For example: https://accounts.google.com/o/oauth2/auth?redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&response_type=code&client_id=407408718192.apps.googleusercontent.com&scope=profile+email&access_type=offline&prompt=select_account

Is it possible to be able to correctly select any available Google account to use when using authorisation via the JS client library for Drive?

I've got an existing Google Drive enabled application that's using the Google Java client library and server flow auth.
If you're not logged into the application and navigate to the URL AND you have logged into more than one google account on that browser (only one personal Google account is possible, any additional ones have to be Google business accounts) the OAuth callback offers the options to select which Google Account to use.
However, whilst testing a switch to using the JavaScript client library I'm not able to activate the multiple account selection screen using gapi.auth.authorize. Is it possible to handle multiple accounts using the JS library?
Update : I tried with the immediate parameter false. I can log in as long as I don't change account in the popup. If I do change account, I get to:
https://accounts.google.com/o/oauth2/auth?client_id=433863057149.apps.googleusercontent.com&scope=https://www.googleapis.com/auth/drive.file+https://www.googleapis.com/auth/drive.install+https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile&immediate=false&redirect_uri=postmessage&origin=https://drivedrawio.appspot.com&proxy=oauth2relay593063763&response_type=token&state=701344514&authuser=1
in a new tab and nothing happens. I've made a video to demonstrate.
Update 2 : This bug against the JS client library for the need for double selection of mulitple account has been accepted.
You are not getting the multi user selection screen because of the following parameter: authuser=0
This automatically selects the first account you are signed-in with (authuser=1 would select the second etc...).
It's currently not possible to remove that param using the client library because the client library sets it automatically to 0 (this is why it claims not to handle multi-accounts) if there is no value so one way is to override it to -1 for example, this will show the multi-account chooser. Then you could also ask to access the user's profile or email at the same time you ask access to other APIs and fetch either the email of the user or its ID. Then on subsequent auth you can specify the user_id param which wil bypass the user-selection screen.
So in practice, first authorize like this:
gapi.auth.authorize({client_id: <Your Client ID>,
scope: 'https://www.googleapis.com/auth/drive openid', // That requires access to Google Drive and to the UserInfo API
authuser: -1});
The only problem with the above is that the auto-refresh of the client library will not work because every auth will by blocked at the multi-account selection screen.
The trick is to get the ID of the user using the UserInfo API, save that ID in a session cookie and use it on subsequent auth like that:
gapi.auth.authorize({client_id: <Your Client ID>,
scope: 'https://www.googleapis.com/auth/drive openid',
user_id: <The User ID>,
authuser: -1});
Specifying the User's ID will make sure the multi-account chooser is bypass and will allow the auto-refresh of the token from the client lib to work again.
For reference, other URL param that impact the User flow are:
user_id: similar than authuser (bypasses the multi-account selection screen) but you can use email address (e.g. bob#gmail.com) or the User ID you get from our Open ID Connect endpoint/Google+ API/UserInfo API
approval_prompt: default is auto, can be set to force to make sure that the approval/grant screen gets shown. This makes sure that the gant screen is not bypassed on subsequent auth (after first time).
immediate: immediate is a bit tricky, when set to true it will bypass the grant screen (kinda like approval_prompt=auto) if the user already granted approval previously, but if the user has not granted approval previously you will get redirected with an error: error=immediate_failed. If set to false it won't add special behavior and therefore fallback on the behavior setup by the approval_prompt value.
Note: immediate=true and approval_prompt=force is an invalid combination.
I think the client library is using the immediate param so that if he gets the error=immediate_failed it will restart an auth flow without the authuser param, but that's only speculations :)
The OAuth grant access page is only shown when not in immediate mode, does it work as expected if you set the immediate parameter to false?
According to http://code.google.com/p/google-api-javascript-client/issues/detail?id=11
multi-login isn't supported by the Javascript client
Pay attention to authuser parameter. Set this to "2" for example and you will be prompted for login even if you are authenticated already.

Resources