Everything is ok before token exchange. I found that Google Home showed "something went wrong,try again." It seems that the account linking was failed. I checked the official document, but I could not find the point that where is wrong.
[enter image description here](https://i.stack.imgur.com/8NzVp.png)
Our OAuth server's log:
14:30:09.322 [https-jsse-nio-9000-exec-10] DEBUG o.s.s.w.FilterChainProxy - [doFilterInternal,218] - Securing GET /oauth2/authorize?response_type=code&client_id=home-control-google&redirect_uri=https://oauth-redirect.googleusercontent.com/r/smarthome-63b16&state=AGsGMl0x-_cveABQcrOPo1I0RVk6fFwzA328sn87humHtmb_d33ppy7MtK0bnqRKJnKKocsJlIGBZyqUBfZnmskiIi5lFU4Kfus9gVFJeQAqyWoKOUwKUbKo5xl3ieM-ElcYYqMJJ0M4IJ5L171QldMLmeAoIJPlSoIgB4-cTx5NQoXYdcFgj4deBZ8p1GA1ucuT_UlTc72irf8GXlLg19geMnJ0W6-PE8cRlx0gN22Qj8AzsmXRRj_h0N6unvRIIfJI-7NaFdmVpYVQBuXzZYi-ajjcLLhiQYLSveVFnbSv-HS2P8mRuZvXhooPoqnj9j7yg0TPDaXPsS3myHb7G1Ka9UHIXHy6yQnEtboQQhLPfHzw204raLk4FzxzUqF4RGz7I8RZu8ExGopO0NkXk4xHn51oLJumyAs6FRJ6n38sYw43yWboa1q3KjAqiPs-2AxqHofL1Hzq-xmWKvKNx5D1i80toVi3nIQys_EPOje89qWH6cWgcuiJ2s4-l_ZIkuw0GK1YT61_dg9XSW2ACJ72agnY2k81vTZYJt1yuh_kGgg83_oqbjcsazr2x9gF_beVxOxq65H9xxYE0D8m2tiNJRaS5CUvygQLJjqCoOy1JozI0sgS9dy6warYk7mc9KPg27e5LagQmEYdghtG_5t5iluzNX4jag
14:30:09.353 [https-jsse-nio-9000-exec-10] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - [readSecurityContextFromSession,189] - Retrieved SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=org.springframework.security.core.userdetails.User [Username=linesware, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[ROLE_USER]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=58.56.179.134, SessionId=E1CD90937DE27B197B6DA53D47FA0454], Granted Authorities=[ROLE_USER]]]
14:30:09.384 [https-jsse-nio-9000-exec-10] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - [doFilter,109] - Set SecurityContextHolder to SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=org.springframework.security.core.userdetails.User [Username=linesware, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[ROLE_USER]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=58.56.179.134, SessionId=E1CD90937DE27B197B6DA53D47FA0454], Granted Authorities=[ROLE_USER]]]
14:30:11.556 [https-jsse-nio-9000-exec-10] DEBUG o.s.s.w.DefaultRedirectStrategy - [sendRedirect,57] - Redirecting to https://oauth-redirect.googleusercontent.com/r/smarthome-63b16?code=O1h-RSPrRnKn45aWutuafiC3EkB_jVVJU-AJfRwdB177-xq1BIJ2fHbftdaMNHZ1Zv70YkKvtHkHZGKO5kAwoqYGmK0ATXAAnSYmyNg_cdQ5Q9V2YnVhs3RUkUr1lYtb&state=AGsGMl0x-_cveABQcrOPo1I0RVk6fFwzA328sn87humHtmb_d33ppy7MtK0bnqRKJnKKocsJlIGBZyqUBfZnmskiIi5lFU4Kfus9gVFJeQAqyWoKOUwKUbKo5xl3ieM-ElcYYqMJJ0M4IJ5L171QldMLmeAoIJPlSoIgB4-cTx5NQoXYdcFgj4deBZ8p1GA1ucuT_UlTc72irf8GXlLg19geMnJ0W6-PE8cRlx0gN22Qj8AzsmXRRj_h0N6unvRIIfJI-7NaFdmVpYVQBuXzZYi-ajjcLLhiQYLSveVFnbSv-HS2P8mRuZvXhooPoqnj9j7yg0TPDaXPsS3myHb7G1Ka9UHIXHy6yQnEtboQQhLPfHzw204raLk4FzxzUqF4RGz7I8RZu8ExGopO0NkXk4xHn51oLJumyAs6FRJ6n38sYw43yWboa1q3KjAqiPs-2AxqHofL1Hzq-xmWKvKNx5D1i80toVi3nIQys_EPOje89qWH6cWgcuiJ2s4-l_ZIkuw0GK1YT61_dg9XSW2ACJ72agnY2k81vTZYJt1yuh_kGgg83_oqbjcsazr2x9gF_beVxOxq65H9xxYE0D8m2tiNJRaS5CUvygQLJjqCoOy1JozI0sgS9dy6warYk7mc9KPg27e5LagQmEYdghtG_5t5iluzNX4jag
14:30:11.556 [https-jsse-nio-9000-exec-10] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - [doFilter,120] - Cleared SecurityContextHolder to complete request
Exchange authorization codes for access tokens
Account Linking through Google Home App consists of two steps: Users are sent to your Authorization Url to provide credentials and complete the consent flow. Once this process is completed successfully, your server gets a token exchange request containing the authorization code at your Token Url. In order to debug this flow, you might need to understand if your credentials exchange completes successfully. You can learn more from the Account Linking Documentation for Google Home.
If you still have issues after this step, make sure to take a look at the Troubleshooting flow. You can also go through the introductory codelab to try these out in a brand new project with a functioning OAuth 2.0 implementation to compare against your project/implementation.
Related
I am trying to configure a third party web application to use Azure AD as the OIDC provider. The authentication works fine, however I am looking for some claims and not able to find an ID or Access Token. Here is the flow as I am seeing it
Call to the login page of the web application. This gets a 302 redirect to the Microsoft OAuth endpoint as below
The URL is https://login.microsoftonline.com/-tenantid-/oauth2/v2.0/authorize?client_id=-clientid-&redirect_uri=-encodedCallbackURI-&response_type=code&scope=openid+email+profile&state=123 This does a 302 to below URL
Next call is to https://login.microsoftonline.com/-tenantid-/oauth2/v2.0/authorize?client_id=-clientid-&redirect_uri=-encodedCallbackURI-&response_type=code&scope=openid+email+profile&state=123&**sso_nonce=O.eyJ0eXAiOiJK......**&client-request-id=-guid-&mscrid=-guid- This returns a 200
Next is the redirect back to the hosted web application indicated in teh callback - https://webApplicationURL/callback?code=0.AQ4Ayjxg80......&state=123&session_state=5b7c2e43-9eab-4bb1-9f24-d020f144d30d
At this point, the user has successfully been authenticated. However, I would like to find the ID or Access Token received.
The sso_nonce(in #3) is in a JWT format but has no claims.
The code(in #4) doesn't have any of the claims either and doesnt really seem to be a JWT token format.
So where is the ID Token or Access Token that I can use to decode and see what claims are getting passed (or not)?
Thanks in advance,
Jake.
To get tokens while calling login page of the web application, you can execute the below request in browser by including response_type as id_token+token:
https://login.microsoftonline.com/<tenant_ID>/oauth2/v2.0/authorize?
client_id=da5daf42-xxxx-xxxx-xxxxxx04a52 //your AppID
&response_type=id_token+token //Required
&redirect_uri=https://jwt.ms //your Redirect URL
&response_mode=fragment
&scope=openid+profile+email
&state=12345
&nonce=678910
Make sure to enable tokens for your web application before executing the above request like below:
Go to Azure Active Directory -> App Registrations -> Your App -> Authentication -> Enable tokens -> Save
I tried to reproduce the same in my environment and got the below results:
When I executed the above-mentioned request in the browser, it asked me to sign in like below:
After successful sign-in, it took me to the redirect URL with tokens in the address bar like below:
When you copy-paste the above in Notepad or any, you can find both access_token and id_token like this:
I got the claims successfully when I decoded the token like below:
Reference:
OpenID Connect (OIDC) | Microsoft Docs
I'm wondering if anyone has run into this problem. I'm trying to authenticate to OneDrive using AAD v2.0, and the device code flow. My app has the following permissions configured in the Azure portal:
Microsoft Graph:
email
Files.ReadWrite.All
offline_access
openid
profile
User.Read
Each time I try to authenticate, I get the following error message from the token endpoint:
AADSTS70011: The provided value for the input parameter 'scope' is not valid. One or more scopes in 'https://graph.microsoft.com/.default openid offline_access' are not compatible with each other.
However, when I use the usual authorization code flow, it works. Similarly, if I use the scope https://graph.microsoft.com/Files.ReadWrite.All openid offline_access instead of https://graph.microsoft.com/.default openid offline_access, it also works.
Is there something about the .default scope that is incompatible with the device code flow?
More info:
The app can be used by "Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)". I'm authenticating to the "consumers" tenant because I want to access my personal OneDrive.
Just remove openid offline_access from the scope, it should be https://graph.microsoft.com/.default, when you use /.default, they are not needed, all permissions registered by the application will be included.
Reference - https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope
Update:
I can reproduce your issue with /consumers and a personal account in the auth url, if I modify it to /<tenant-id>, it works fine, you could refer to the steps below.
1.In the postman, use the request below.
Request URL:
POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/devicecode
Request Body:
client_id=<client-id>
scope=https://graph.microsoft.com/.default
2.In the browser, navigate to the https://microsoft.com/devicelogin, input the code and login your user account, the app will let you consent the permission, click the Accept.
3.After login successfully, in the postman, use the request below.
Request URL:
POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
Request Body:
grant_type: urn:ietf:params:oauth:grant-type:device_code
client_id: <client-id>
device_code: <device_code in the screenshot of step 1>
I am trying to integrate SSO in an existing java/jsp based application(SP) with help of Spring Security SAML extension and ADFS 4(IP). After I land in the ADFS SSO page from SP login link and enter credentials, application is not able to validate the ADFS response and giving "HTTP Status 401 - Authentication Failed: Error validating SAML message" error.
However from logs I can see the Assertion is already decrypted successfully and Attributes are being printed. So I am not able to understand why it is giving Authentication Failed error. Pl. help. I am providing log data below. The java application is hosted in Tomcat server.
20-08-2019 11:52:20,003 DEBUG org.apache.xml.security.signature.Reference:? - Verification successful for URI "#_530eaef7-3196-431c-bef8-36fc7c76ef27"
20-08-2019 11:52:20,003 DEBUG org.apache.xml.security.signature.Manifest:? - The Reference has Type
20-08-2019 11:52:20,006 TRACE org.springframework.web.context.support.XmlWebApplicationContext:322 - Publishing event in Root WebApplicationContext: org.springframework.security.authentication.event.AuthenticationFailureServiceExceptionEvent[source=org.springframework.security.saml.SAMLAuthenticationToken#43b19eef: Principal: null; Credentials: [PROTECTED]; Authenticated: false; Details: null; Not granted any authorities]
20-08-2019 11:52:20,006 DEBUG org.springframework.security.saml.SAMLProcessingFilter:346 - Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Error validating SAML message
20-08-2019 11:52:20,006 DEBUG org.springframework.security.saml.SAMLProcessingFilter:347 - Updated SecurityContextHolder to contain null Authentication
20-08-2019 11:52:20,007 DEBUG org.springframework.security.saml.SAMLProcessingFilter:348 - Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler#90f53ff
20-08-2019 11:52:20,007 DEBUG org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler:56 - No failure URL set, sending 401 Unauthorized error
20-08-2019 11:52:20,007 DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository:269 - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
Problem: Missing OAuth 2 Refresh Token.
The problem is that the localhost version receives a Refresh Token as part of the granted token but the same code running in GCE does not.
Details:
I have written a Python Flask application that implements Google OAuth 2.0. This web application runs in the cloud with a verified domain name, valid SSL certificate and HTTPS endpoint. This web application unmodified also runs as localhost. The differences between the runtime is that the localhost version does not use TLS. There are no other differences in the code flow.
Other than the Refresh Token is missing and I cannot automatically renew a token, everything works perfectly.
I have researched this issue extensively. API problems such as access_type=offline etc are correctly implemented otherwise I would not get a Refresh Token in the localhost version.
I am using the requests_oauthlib python library.
gcp = OAuth2Session(
app.config['gcp_client_id'],
scope=scope,
redirect_uri=redirect_uri)
# print('Requesting authorization url:', authorization_base_url)
authorization_url, state = gcp.authorization_url(
authorization_base_url,
access_type="offline",
prompt="select_account",
include_granted_scopes='true')
session['oauth_state'] = state
return redirect(authorization_url)
# Next section of code after the browser approves the request
token = gcp.fetch_token(
token_url,
client_secret=app.config['gcp_client_secret'],
authorization_response=request.url)
The token has refresh_token when running in localhost but not when running with in the cloud.
This Google document discusses refresh tokens, which indicates that this is supported for web applications.
Refreshing an access token (offline access)
[Update 11/18/2018]
I found this bug report which gave me a hint to change my code from this:
authorization_url, state = gcp.authorization_url(
authorization_base_url,
access_type="offline",
prompt="select_account",
include_granted_scopes='true')
to this:
authorization_url, state = gcp.authorization_url(
authorization_base_url,
access_type="offline",
prompt="consent",
include_granted_scopes='true')
Now I am receiving the Refresh Token in the public server version and the localhost version.
Next I searched for documentation on the prompt option and found this:
OpenID Conect prompt
prompt (Optional)
A space-delimited list of string values that specifies whether the
authorization server prompts the user for reauthentication and
consent. The possible values are:
none
The authorization server does
not display any authentication or user consent screens; it will return
an error if the user is not already authenticated and has not
pre-configured consent for the requested scopes. You can use none to
check for existing authentication and/or consent.
consent
The authorization server prompts the user for consent before returning
information to the client.
select_account
The authorization server
prompts the user to select a user account. This allows a user who has
multiple accounts at the authorization server to select amongst the
multiple accounts that they may have current sessions for.
If no value is specified and the user has not previously authorized access, then
the user is shown a consent screen.
I think the Google documentation should be updated. On the same page, the following text appears:
access_type (Optional)
The allowed values are offline and online. The
effect is documented in Offline Access; if an access token is being
requested, the client does not receive a refresh token unless offline
is specified.
That statement caused me a lot of confusion trying to debug why I could not obtain a Refresh Token for the public server version but I could for the localhost version.
I am using PingFederate with OpenID Connect. And I am having an issue while logging out from the grant management page.
I configured my IdP adapter session state settings as global. So, if i use one of those Logout endpoints, i am being logged out from all other RPs successfully.
And after logout, if I try to get the grant management page via this endpoint ~/as/grants.oauth2, login page is prompted so SLO works fine. But when i go the other endpoint which is ~/as/oauth_access_grants.ping i can get the page without logging in. So, do you have any idea, why global HTML Form IdP adapter logout endpoint does not log me out from that endpoint and log me out from other endpoint?
I am using the endpoint which is defined on the adapter.
I have hierarchic adapters. A parent adapter holds the global settings and set as default. Children are accepting global settings too on their session settings.
So, when i call one of these adapter's endpoint (the ones shares global settings), all my sessions which has global settings are being removed from the session map. So a kind of selective SLO is happening.
I checked the server logs, each globally set adapters are added their sessions to the state map as HtmlFormIdpAuthnAdapter:SESSION.
org.sourceid.saml20.service.impl.localmemory.InterReqStateMgmtMapImpl] getAttr(key: GEZIxxzzgrJ1Wq0vFoSY09, name: HtmlFormIdpAuthnAdapter:SESSION
Even the grants management page.( ~/as/grants.oauth2). But the other grants management endpoint put its session to the states map as name: attrs and name: csrfToken.
[org.sourceid.saml20.service.impl.localmemory.InterReqStateMgmtMapImpl] getAttr(key: GEZIxxzzgrJ1Wq0vFoSY09, name: attrs) 2016-02-18 08:30:39,404 tid:b4ryqAPIEA6R0ywXzVmC6XtykHc DEBUG [org.sourceid.saml20.service.impl.localmemory.InterReqStateMgmtMapImpl] getAttr(key: GEZIxxzzgrJ1Wq0vFoSY09, name: csrfToken)
So basically when i revoke the session via adapter endpoint it removes all HtmlFormIdpAuthnAdapter:SESSION values.
removeAttr(key: GEZIxxzzgrJ1Wq0vFoSY09, name: HtmlFormIdpAuthnAdapter:SESSION) 2016-02-18 08:27:35,407 DEBUG [com.pingidentity.jgroups.MuxInvocationHandler] invocation of removeA ttr on InterReqStateMgmtMapImpl state map size:11 attributes map size9 2016-02-18 08:27:35,409 tid:b4ryqAPIEA6R0ywXzVmC6XtykHc DEBUG [org.sourceid.saml20.service.impl.grou prpc.InterRequestStateMgmtGroupRpcImpl] called mode:GET_MAJORITY removeAttr() on [10.0.12.90:7600, 1 0.0.12.126:7600]
But the ones which is added by https://localhost:9031/as/oauth_access_grants.ping is still remains. So i can get the grants management page from this endpoint, but the other endpoint requires a login.
And I also tried idp/startSLO.ping logout endpoint.
It works and revokes all session (even the last one) ONLY if i get access token on that session.
Otherwise, if i login to the grants management page directly and call the idp/startSLO.ping, i get an error from server.
*###Server1### 2016-02-18 08:31:34,705 tid:b4ryqAPIEA6R0ywXzVmC6XtykHc DEBUG [org.sourceid.websso.servlet.IntegrationControllerServlet] GET: https://localhost:9031/idp/startSLO.ping 2016-02-18 08:31:34,705 tid:b4ryqAPIEA6R0ywXzVmC6XtykHc DEBUG [org.sourceid.saml20.service.impl.grouprpc.PreferredNodes] [] -> indices to addresses -> [10.0.12.90:7600, 10.0.12.126:7600] 2016-02-18 08:31:34,708 DEBUG [org.sourceid.saml20.service.impl.localmemory.IdpSessionRegistryMapImpl] getRegistered(3AeDfSHVS1F0JU4nwgLsPJ) found null authn beans 2016-02-18 08:31:34,708 DEBUG [com.pingidentity.jgroups.MuxInvocationHandler] invocation of getRegistered on org.sourceid.saml20.service.impl.localmemory.IdpSessionRegistryMapImpl#e599115{bean->sessionLists=0, assertionId->bean=0, pfsessionid->beanSets=6} 2016-02-18 08:31:34,708 tid:b4ryqAPIEA6R0ywXzVmC6XtykHc DEBUG [org.sourceid.saml20.service.impl.grouprpc.IdpSessionRegistryGroupRpcImpl] called mode:GET_MAJORITY getRegistered() on [10.0.12.90:7600, 10.0.12.126:7600] 2016-02-18 08:31:34,709 tid:b4ryqAPIEA6R0ywXzVmC6XtykHc DEBUG [org.sourceid.saml20.bindings.BindingServiceImpl] Not transporting protocol request message because the HTTP response has been committed (this is a normal condition usually due to an adapter or other component redirecting the user or writing its own content to the response).
SErver2
2016-02-18 08:31:34,706 DEBUG [org.sourceid.saml20.service.impl.localmemory.IdpSessionRegistryMapImpl] getRegistered(3AeDfSHVS1F0JU4nwgLsPJ) found null authn beans 2016-02-18 08:31:34,707 DEBUG [com.pingidentity.jgroups.MuxInvocationHandler] invocation of getRegistered on org.sourceid.saml20.service.impl.localmemory.IdpSessionRegistryMapImpl#dec9571{bean->sessionLists=0, assertionId->bean=0, pfsessionid->beanSets=6}*
And TRACK USER SESSIONS FOR LOGOUT and REVOKE USER SESSION ON LOGOUT is also enabled.
Basically, i need to find a way to make my grants management page use only the defaulthtmlform idp adapter.
I assume you're using the /idp/startSLO.ping endpoint for logout? (and not a defined logout endpoint only on the adapter?)
I believe I was able to reproduce what you're seeing. I suspect you have "TRACK USER SESSIONS FOR LOGOUT" enabled in your OAuth Authorization Server Settings (part of the Asynchronous Front-Channel Logout mechanism (documentation), but you don't have "REVOKE USER SESSION ON LOGOUT" (part of our server side tracking).
Try enabling "REVOKE USER SESSION ON LOGOUT" and see if that resolves the issue.