Can you explain the RP->OP part in openid connect flow? - authentication

I don't understand the 1 part.
For example, I have a website asdf.com and use google OP, so I have a login with google button with a link(something like https://account.google.com/XXX?return_url=asdf.com) to google site on my website.
So the user will click this button to login, so I think the 1 step should be enduser -> OP ? why RP -> OP ?

Lets look at this in pieces might as well take them all. This is called the Oauth2 dance or three legged Oauth2 flow. There are three steps in the dance to get authorization. There are two main players the Client Application and the Authentication server with the resource owner playing a side roll.
Step 1:
[Client Application] contacts Authentication sever. Says i have a user who would like to consent to login to my application.
[Authentication server] sure no problem user must login first then I will display them a consent screen
https://accounts.google.com/o/oauth2/auth?client_id={clientid}.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/analytics.readonly&response_type=code
[Resource owner (user)] Hits consent.
Step 2:
[Authentication server] responds to the client. Hey your user says you can access this here is an authorization code.
[Client Application] Thanks for the authorization code here have it back and my client id and secret (client id and secret are baslicly login and password for the client identifying it to the authorization server) this should verify to you that i am me.
https://accounts.google.com/o/oauth2/token
code=4/X9lG6uWd8-MMJPElWggHZRzyFKtp.QubAT_P-GEwePvB8fYmgkJzntDnaiAI&client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code
Step 3.
[Authentication server] awesome looks like you here have an access token and possibly a refresh token as well.
Comments:
Open id connect is basically built on top of Oauth2 the main difference is that the scope you send is openid .
You can test it here if you want for fun Oauth2 playground

Yes I would say you are right: The first request to the OP comes from the end user.
The RP normally builds the request to the OPs authorise endpoint, but it then either redirects the end user's browser to that endpoint (e.g. via an HTTP 302 response) or it places the built URL as an action on a link/button on the html page returned from the RP to the end user.
This appears to be missing on the diagram.

Related

FusionAUth : How to merge user signup + sign in FusionAuth, to make user Auto login to web application

We are trying FusionAuth & looking to have a single step flow for Sign up + Sign In.
After user signs up, we want to show/land him directly to our application's dashboard page (without showing him login page in between the flow). The authentication should happen but internally i.e we are expecting OAuth2 standard IdToken in response to "WebApplication" so that web application can use IdToken to allow user to application.
Please note that we don't want to use approaches where we need to pass Username/password to our web application, don't want to handle user credentials. Also that we dont want to use Authentication Tokens returned in Registration flow because AuthenticationTokens are not that secure, looking to use OAuth2 based IdToken instead.
I have came across this post "https://fusionauth.io/community/forum/topic/165/taking-a-user-directly-to-the-registration-page/3" and tried following request, but it is showing Login page instead of registration.
/oauth2/register?client_id=<Configured_client_id>&redirect_uri=<Configured_redirect_uri>&response_type=code
(I have not used CSRF parameter though)
Please can you suggest why its showing Login Page?
You should be able to have a user register and be sent directly to your application, as long as you set the correct redirect_uri and put that on the registration URL:
https://local.fusionauth.io/oauth2/register?client_id=c50329fa-93e5-4618-8d9f-73d0ab069a23&response_type=code&redirect_uri=https%3A%2F%2Fapp.example.com%2F
The application will then receive a code that can be exchanged for an access token. You can call the userinfo endpoint with that token and get user information like email address, etc.
What you won't get that it seems like you might want is an id token. For that you'll have to send the user through the login process with a scope of profile. However, you could mind your own 'id token'-lite using the values from the userinfo endpoint and the JWT vending: https://fusionauth.io/docs/v1/tech/apis/jwt/#vend-a-jwt

Authentication using Azure AD, failing at last step accessing Skype for Business

I am following this guide (https://learn.microsoft.com/en-us/skype-sdk/ucwa/authenticationusingazuread) in order to access Skype for Business. Everything goes fine till the last part but let's do step by step. I am building my .net console application to do this but in order to explain you properly the problem I am having I will show you directly the http calls through Insomnia (software used to make http calls).
Step 1:
GET request towards https://webdir.online.lync.com/autodiscover/autodiscoverservice.svc/root
I hit 200 and as answer I receive this:
Step 2:
I use the user link.
So I send an http request to https://webdir1e.online.lync.com/Autodiscover/AutodiscoverService.svc/root/oauth/user and I get a 401 Unauthorized (everything still correct).
In the header of the answer it points me to the Identity Provider to ask for authorization (authorization_uri)
Step 3: I use that link to authorize my app, which has its own client_Id (that I hide in the following screenshot).
This is how I compose the call:
If I send this http request I get redirected to the page where it asks my personal login and by inserting my credentials I succesfully login and hit 404, where in the answer I receive back my access token.
Step 5: I use the access token towards the same AutodiscoverService link of step 1. This is to register my application. I hit 200 and I receive back the link to access Skype for Business.
Finally (and this is where things go wrong) I send a POST request towards the applications link with the Bearer token, and I receive a 403 Forbidden. I think I am following correctly the guide but I can't figure out why I can access the resource at the last step.
EDIT:
The permissions are granted. I hide the name since it contains the name of my company. But it is the same of the domain of my login.
So the token you generated authorizes you to access resources at https://webdir1e.online.lync.com which you've done to fetch a new set of resources including the "application" resouce which is on a DIFFERENT host: https://webpooldb41e14.infra.lync.com.
You actually have to get another OAuth token now which authorizes you for the application resource and then you can POST to that to generate your session in UCWA.
As a side note... If you've defined your own single-tenant application in Azure that has been granted rights to SkypeForBusinessOnline then I think you should be targeting authorization and authentication endpoints of the form:
https://login.microsoftonline.com/{tenantID}/oauth2/v2.0/authorize
https://login.microsoftonline.com/{tenantID}/oauth2/v2.0/token
Also I should add, if you're trying to write a trusted secure client that users in your company will use I would suggest looking up the Resource Owner Password Credentials auth flow. It allows you to directly hit the token endpoint I mentioned above and exchange username/password credentials for an access token. Then you can manage auto-discovery and application creation easily under the hood without getting re-directed back and forth to Azure.
https://learn.microsoft.com/mt-mt/azure/active-directory/develop/v2-oauth-ropc

Matching OAuth request to response

Focussing on the authorization_code grant type (server to server) I am confused as to how a client (in this case a web server app) matches a response (positive) to the outgoing request.
The response is a redirect with code in the URL (not interested in the token part yet). How does the web server know who this code belongs to?
After working with OAuth now for a couple of weeks I understand now how this works.
If we are talking about granting application A logged in user U authorisation to access resource R.
The user U starts off in application A and is logged in there in the browser which means in most cases that a cookie is set with a session token.
The user U is redirected to application / resource R where he would login (or be automatically logged in using a resource R session cookie).
Presuming he grants the request he is then redirected in the browser back to application A with a code C.
Here again the seesion cookie for application A from step 1 is presented to the server but along with the code C. The server of application A can then use this code to get a token for the user U.

How to authenticate user with just a Google account on Actions on Google?

Currently Google Assitant includes an easy way to request non-identifiable information about the user and a detailed flow to authenticate the user on a third party service through OAuth2. What about if all I need is have the user authenticate on Google itself? I tried filling in the account linking flow using Google OAuth2 information, but that seems not to work. If that last thing is supposed to work fluently than that would be enough of an answer.
Context: Users already authenticate only with Google on a related webpage. All I need is to link this already authenticated account with the less-authenticated account on Google Assistant.
Update, 25 Oct 2018:
As of 13 September 2018, there is now a much simpler way to access the user's account if your project uses Google Sign-In. Google Sign-In for Assistant will give you an ID Token with information about the user, including their Google ID, with their permission. This permission can be granted just using voice and is fairly streamlined.
You can combine this with a web- or app-based Google Sign-In to get their permission to access OAuth scopes if you need to access Google's APIs.
Update, 25 Oct 2017:
As of around 4 Oct or 7 Oct, Google has updated their policy (again) to restore language restricting OAuth endpoints that are valid. The terms now include
When implementing account linking using OAuth, you must own your OAuth endpoint
and it appears (from the comments below) that they now check for the Google endpoints to prevent this method from working.
At this point, the only thing you can do is setup your own OAuth2 server.
Original Post:
Broadly speaking, the auth tasks you need to do are in four parts:
Configure your project (in the cloud console) so that the Calendar API is enabled and that the OAuth2 client is correctly configured.
Configure the Action for account linking in the action console.
Configure the Actions on Google Integration for your API.AI Agent to indicate that sign-in is required.
When API.AI calls your webhook to fulfill an Intent, it will include an auth token as part of the JSON. You can use this token to make calls to the Google APIs you need.
Configure Cloud Project
You need to configure your cloud project so that it has access to the Google APIs you need and setup the OAuth2 Client ID, Secret, and Redirect URI.
Go to https://console.cloud.google.com/apis/dashboard and make sure you have the project you're working with selected. Then make sure you have the APIs you need enabled.
Select the "Credentials" menu on the left. You should see something like this:
Select "Create credentials" and then "OAuth client ID"
Select that this is for a "Web application" (it is... kinda...)
Enter a name. In the screen shot below, I used "Action client" so I remember that this is actually for Actions on Google.
In the "Authorized Redirect URIs" section, you need to include a URI of the form https://oauth-redirect.googleusercontent.com/r/your-project-id replacing the "your-project-id" part with... your project ID in the Cloud Console. At this point, the screen should look something like this:
Click the "Create" button and you'll get a screen with your Client ID and Secret. You can get a copy of these now, but you can also get them later.
Click on "Ok" and you'll be taken back to the "Credentials" screen with the new Client ID added. You can click the pencil icon if you ever need to get the ID and Secret again (or reset the secret if it has been compromised).
Configure the Action Console
Once we have OAuth setup for the project, we need to tell Actions that this is what we'll be using to authenticate and authorize the user.
Go to https://console.actions.google.com/ and select the project you'll be working with.
In the Overview, make your way through any configuration necessary until you can get to Step 4, "Account Linking". This may require you to set names and icons - you can go back later if needed to correct these.
Select the Grant Type of "Authorization Code" and click Next.
In the Client Information section, enter the Client ID and Client Secret from when you created the credentials in the Cloud Console. (If you forget, go to the Cloud Console API Credentials section and click on the pencil.)
For the Authorization URL, enter https://accounts.google.com/o/oauth2/v2/auth
For the Token URL, enter https://www.googleapis.com/oauth2/v4/token
Click Next
You now configure your client for the scopes that you're requesting. Unlike most other places you enter scopes - you need to have one per line. Then click Next.
You need to enter testing instructions. Before you submit your Action, these instructions should contain a test account and password that the review team can use to evaluate it. But you can just put something there while you're testing and then hit the Save button.
Configure API.AI
Over in API.AI, you need to indicate that the user needs to sign-in to use the Action.
Go to https://console.api.ai/ and select the project you're working with.
Select "Integrations" and then "Actions on Google". Turn it on if you haven't already.
Click the "Sign in required for welcome intent" checkbox.
Handle things in your webhook
After all that setup, handling things in your webhook is fairly straightforward! You can get an OAuth Access Token in one of two ways:
If you're using the JavaScript library, calling app.getUser().authToken
If you're looking at the JSON body, it is in originalRequest.data.user.accessToken
You'll use this Access Token to make calls against Google's API endpoints using methods defined elsewhere.
You don't need a Refresh Token - the Assistant should hand you a valid Access Token unless the user has revoked access.
After contacting Google the current situation seems to be that you should set up your own OAuth2 server, and then on the login screen of your OAuth2 server you should start the Google OAuth2 flow.
you have to have your own endpoint with Google Oauth2 - it is correct that you can't use Google Oauth itself as a provider. To use the Google OAuth service, you can use a "sign in with Google" button in your own endpoint instead.
Source: Contacting Google Actions on Google Support
Kind of speechless right now... as this seems to be a huge oversight on Google's part.
I am able to make it work after a long time.
We have to enable the webhook first and we can see how to enable the webhook in the dialog flow fulfillment docs
If we are going to use Google Assistant, then we have to enable the Google Assistant Integration in the integrations first.
Then follow the steps mentioned below for the Account Linking in actions on google:-
Go to google cloud console -> APIsand Services -> Credentials -> OAuth 2.0 client IDs -> Web client -> Note the client ID, client secret from there
-> Download JSON - from json note down the project id, auth_uri, token_uri
-> Authorised Redirect URIs -> White list our app's URL -> in this URL fixed part is https://oauth-redirect.googleusercontent.com/r/ and append the project id in the URL
-> Save the changes
Actions on Google -> Account linking setup
1. Grant type = Authorisation code
2. Client info
1. Fill up client id,client secrtet, auth_uri, token_uri
2. Enter the auth uri as https://www.googleapis.com/auth and token_uri as https://www.googleapis.com/token
3. Save and run
4. It will show an error while running on the google assistant, but dont worry
5. Come back to the account linking section in the assistant settings and enter auth_uri as https://accounts.google.com/o/oauth2/auth
and token_uri as https://accounts.google.com/o/oauth2/token
6. Put the scopes as https://www.googleapis.com/auth/userinfo.profile and https://www.googleapis.com/auth/userinfo.email
and weare good to go.
7. Save the changes.
In the hosting server logs, we can see the access token value and through access token, we can get the details regarding the email address.
Append the access token to this link "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" and we can get the required details in the resulting json page.
accessToken = req.get("originalRequest").get("data").get("user").get("accessToken")
r = requests.get(link)
print("Email Id= " + r.json()["email"])
print("Name= " + r.json()["name"])
You need to implement the Oauth protocol with whatever Google Assistant app you are developing. Let me be a bit more clear:
The user is on the assistant, you need to link him to any data
you have on your App side
The access to the data you have about
your user is protected by an access token
Google then needs to
ask you for this token to have access to this resource
When
google has the token it can send it to the app so it validates every
requests to get the resource.
This is why you need to implement your own oauth server (Honestly it is just two more endpoints in your application): the identity is checked on google's side, but the link between the user and the resource to access can only be known by you.
The process above is valid, you just need to specify your own token endpoint and your own auth endpoint.
Note that if you only want to check that the user is logged in into google and get his email, you just need to implement the streamlined identity flow that does not require the /auth endpoint (Automatically Sign Up Users with Streamlined Identity Flows)
That beeing said I implemented the flow but get the same error :
expected_inputs[0].possible_intents[0]: Transactions/Identity API must be enabled before using.

openidconnect.server, third party providers & redirection

I'm currently building my an openid connect server using https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server and asp.net core identity as a backing store. I'm aware of the protocols, the flows and the security holes.
The current setup is as follows:
[server] - the authorization server & resource server
[front-end] - an angularJS application
[third-party-provider] - Google
[external-app] - a second application which want to use a token from [server]
Both the [front-end] and the [external-app] are registered as clients for the [server]. So, they are allowed to retrieve tokens. The login page is build in the [front-end].
Keep in mind, that the login page etc is shown by the [front-end] application (instead of returning a AuthView from the AccountController)
Imagine i'd want to login with the [external-app] to get an identity from [server]. The login page is shown by [front-end]. Then the flow will be the following:
1. [external-app] -> http://[server]/account/authorize?client_id=[external-
app-clientid]&response_type=token&redirect_uri=http://[external-app-
redirecturi]
2. [front-end] -> matches route -> show login page
3. [front-end] -> user clicks on login with google
4. [front-end] -> redirect to 'http://[server]/account/authorize/connect?
provider=Google&redirect_uri=http://[front-
end]/account/thirdparty/authorized&response_type=code&client_id=[front-
end-clientid]
5. [server] -> no identity found, save request in session and let the user
login at the [third-party] (using ChallengeResult and also passing in the
request id which was stored in session)
6. [third-party-provider] user logs in
7. [front-end] -> http://[front-end]/account/thirdparty/authorized recieved
the code
8. [front-end] -> exchange authcode for token with [server] using
http://[server]/account/token&grant_type=authorization_code&code=
[code]&redirect_uri=http://[front-
end]/account/thirdparty/authorized&client=[front-end-clientid]
9. [server] -> generate claims and return token
10. [front-end] -> token recieved
A thing i'm missing (and it might be an implementation flaw, thought flaw or whatever) is that i need to redirect back to the [external-app] with the given token. Do i need to do that on the [front-end]? It feels off and i'm kinda sure i'm mixing / matching stuff wrong. Can anyone help me out?
Thanks in advance!
PS yes, i know, should be https. Above is for example purpose ;)
With interactive flows like the implicit flow, the important thing to remember is that you have to redirect the user to the identity provider's authorization endpoint so it has a chance to prepare an authorization response.
You're free to decide what happens between the moment your identity provider receives the authorization request and the moment it returns an authorization response, but you can't redirect the user from your "front-end" application directly to the "external application" because it has no way to generate an authorization response (it's not its role).
Consider reworking your flow so your front-end app redirects your users to the authorization server, that will itself redirect them to your external app.