Google Action not refreshing access token - oauth

The account linking and authentication proces for my google action works just fine, except once the access token expires, it is not being refreshed.
I have the following settings:
No account creation outside of website
linking type: OAuth & google sign in
Flow: Authorization code
OAuth & google sign in client information:
Entered client id,
Entered client secret,
Entered Authorization Url (seems to work just fine as I am able to authenticate)
Entered Token Url: https://sod.superoffice.com/login/common/oauth/tokens (This is a default url provided by the service I'm authenticating with)
Some additional information about the parameters my external service expects to receive in order to refresh the access token:
https://{env}.superoffice.com/login/common/oauth/tokens?
grant_type=refresh_token&
client_id=4ref5376616343b38d14ddcd804f2654&
client_secret=18f45229e442772a78df5f554e24a456&
refresh_token=nKHwerkjh34Yd6QShsnGKk4cFhTwCv3XtJu9PW2X63MtUMygLdI57BJjwCU0&
redirect_url=http://localhost/callback
The access token expires every hour and then forces me to relink my Google account with the external service. To me this seems to indicate that the access token is not being refreshed.
Any suggestions...?

I fixed it by removing all of the parameters I thought you had to provide at the authorization URL field. Instead of just providing the URL, I also included the parameters such as the redirect url, scope, client id etc.
By just providing the authorization & token URL without any additional parameters I have fixed my issue.

Related

ADFS 2016 - OAuth2 SPA - Get a new token silently

I have a SPA where the user authenticates in ADFS and the application gets an access token. I am trying to use JS code to simulate the functionality of ADAL JS where a hidden iframe is used to make a request to ADFS to get the new token.
This is the 'src' value of the iframe:
https://../adfs/oauth2/authorize?client_id=...&response_type=id_token&redirect_uri=...&prompt=none&domain_hint=...&login_hint=...&nonce=...
The ADFS is configured with two realms: AD and ADLDS (LDAP). Because of this I am not sure what values I need to pass on domain_hint & login_hint parameters for a user in ADLDS.
The request fails with message:
https://....html?client-request-id=...#error=login_required&error_description=MSIS9621%3a+Unable+to+handle+the+OAuth+authorization+request+without+getting+user+input.
The ADFS event viewer shows this error:
Exception details:
Microsoft.IdentityServer.Web.Protocols.OAuth.Exceptions.OAuthNoPassiveException: MSIS9233: There are multiple identity providers found for OAuth Authorization request with prompt set to none. Unable to complete home realm discovery.
Is this functionality actually supported in ADFS 2016? Any idea as to what am I doing wrong?
The prompt=none request parameter says that you want to pass the process the /authorize request without user interaction. But during its processing, there is something that needs user interaction - the server probably doesn't know which identity provider to choose, so it returns the error. If you make the same request just by pasting the /authorize URL to your browser without the prompt=none parameter, the server will probably give you a possibility to choose a provider.
You wrote you would like to get an access token, but your /authorize URL contains response_type=id_token. If you want an access token, the parameter should be response_type=token (see RFC).
Looking at the Azure doc, the domain_hint request param is supported of OpenID Connect, so your request scope parameter should contain openid value. It's also necessary for getting an ID token (if you want it).

Use External Access Token or Local Access Token

I am developing an application using ASP.NET MVC 5.2.2, Web API 2.2 and Katana/OWIN 3.0. The application uses ASP.NET Identity 2.1 for local accounts and database.
I am using OAuth Authorization Server to generate access and refresh token. I have Android and IOS apps which uses my local oauth authorization server. Android and IOS apps uses SDK to login with Facebook, Google, etc. After that the apps will send the (Facebook/Google/etc) access token to the server. The server will validate access token with Facebook/Google/etc.
If it is valid then,
1) Should I generate new local access token(in Auth header) to apps
for all future request?
2) Should the app send me Facebook/Gmail/etc
access token(in Auth header) every time and the server validate the
access token with Facebook/Gmail/etc each time?
3) If local access
token expire, then the server is using refresh token to generate new
access token. Should the server update the access token as well as
refresh token during this time or updating access token is enough?
after you validate your social provider external access token, you need to exchange this external access token with a local access token issued by your authorization server (Local authority). All the details for this implementation can be found here: http://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-angularjs-app/
Let me know if this helps.
Here is the exact steps I have followed to change the external access token with access token issues by Local Authority. The front end is an AngularJS application. You can check the demo application here and see how I'm accessing the web api using Facebook access token http://ngauthenticationweb.azurewebsites.net/
1- AngularJS application sends HTTP GET request to anonymous end point (/ExternalLogin) defined in our back-end API by specifying client_id, redirect_uri, response_type.
2- Once the end point receives the GET request, it will check if the user is authenticated, and let we assume he is not authenticated, so it will notify the middleware responsible for the requested external provider to take the responsibility for this call, in our case it is Google.
3- The consent screen for Google will be shown, and the user will provide his Google credentials to authenticate.
4- Google will callback our back-end API and Google will set an external cookie containing the outcome of the authentication from Google (contains all the claims from the external provider for the user).
5- Google middleware will be listing for an event named “Authenticated” where we’ll have the chance to read all external claims set by Google. In our case we’ll be interested in reading the claim named “AccessToken” which represents a Google Access Token, where the issuer for this claim is not LOCAL AUTHORITY, so we can’t use this access token directly to authorize calls to our secure back-end API endpoints.
6- Then we’ll set the external provider external access token as custom claim named “ExternalAccessToken” and Google middleware will redirect back the end point (/ExternalLogin).
7- Now the user is authenticated using the external cookie so we need to check that the client_id and redirect_uri set in the initial request are valid and this client is configured to redirect for the specified URI.
8- Now the code checks if the external user_id along with the provider is already registered as local database account (with no password), in both cases the code will issue 302 redirect to the specified URI in the redirect_uri parameter, this URI will contain the following (“External Access Token”, “Has Local Account”, “Provider”, “External User Name”) as URL hash fragment not a query string.
9- Once the AngularJS application receives the response, it will decide based on it if the user has local database account or not, based on this it will issue a request to one of the end points (/RegisterExternal or /ObtainLocalAccessToken). Both end points accept the external access token which will be used for verification and then using it to obtain local access token issued by LOCAL AUTHORITY. This local access token could be used to access our back-end API secured end points.

Login to mobile app and web app using oAuth

We have a SSO system which is used by our web applications and we are planning to also write some new mobile/desktop applications. I have been reading about using oAuth 2.0 so a user can natively login using the app (using the password grant type), retrieve an access token and access functionality using the REST web services. The problem is all functionality will not be available within the app, in some cases we have to redirect the user to the web application via a browser. I have read we shouldn't pass the access token in a URL so is there anyway to use oAuth to login to the web application automatically without the user having to submit their username and password again?
Any advice would be much appreciated.
In the mobile app, you could create a nonce (a token that should be used no more than once). Then, add this to the URL when opening a link to the Web page. This token should have some sort of identifier in it. The Web app that serves that page should track these IDs to ensure that it's not sent multiple times (thus, making it a nonce). This would be independent of the OAuth-based authentication. So, a request might look like this:
GET /anything?nonce=eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI5N1Y2ZU9WWlo1VGpPR3dWIiwiY2xpZW50X2lkIjoibXktZ29vZC1tb2JpbGUtYXBwLTIyIiwiYXVkIjoiaHR0cHM6Ly9leGFtcGxlLm9yZy9wYWdlLXRoYXQtaXMtbm90LWluLW15LW1vYmlsZS1hcHAiLCJleHAiOjE1OTg3NTI0NDB9.JoDstXRnC23PE8ZCqk-U-IzSNp_cUYa12HbajI1KGlF-OwRR46QRC_V7brcGOVdo5_Aw1RdpssNWCVFiGDeTBc8wi1lIJW-rgEGH5J1qUi8rL1T-yfy3vdLGPYzJMtHvCeyoEjgmoYOtZcpPSQScBJSRvId3Hdu3QgwcelSwljkeNJbZRCnG25HIqJfC1Cjm9vqHhvUGqtzbgVBUPnICiI8EZyGe3SpH2P4SxctLcgzWad8zJeyPFki3yfBHpqQ3mBWy0BbVdjzgD0mj323q1LWHR4kNkrH7cUJgAg4PlWahOW7Q4qcT3CBJYNtlh008ARqK7XagEQKX45vv5TfSlk2q7Zy06RnV2XwZXfLpyh-ZfURpcsxEJ3O-4NY71XxEqUtEyuisjQdZx5m95uzSrzk75F-ruQ3KYIouiAOAUDuMtFwhwjF68VdDeC4Zwt2q3BHzMBBp-8k1bAXq8e4dmHz0Jbuo9R8MJ2zSrVK6is5nNtNoJvYoXgc0WTA8MFqBj316cT_ouu-U1nTL3GR5sJ_lxorhP6xz0CqNxNY_90-JwOUB0UibUryRiXt-SUPJga36pBQ8eO8--Xupx_WU7CDIFdFvnLgJahD-4KmZcga6wCoqd-KKw3H5-jtbit06XMrKkDiWjz2g4eYhPR6xipbnqyZaaCwtYN4mAMz86ug HTTP/1.1
Host: example.org
Accept: */*
When the JWT-encoded nonce is decoded, you can see this header:
{
"alg": RS256
}
and this body:
{
"jti": "97V6eOVZZ5TjOGwV",
"client_id": "my-good-mobile-app-22",
"aud": "https://example.org/page-that-is-not-in-my-mobile-app",
"exp": 1598752440
}
Now, the API could decide if the nonce is acceptable by:
Check that it's URL is the same as the aud (audience) claim
Check that the nonce has never been seen before (using the jti, JWT ID, claim)
Check that this resource should be possible for this client to request (using the client_id claim)
Check that the nonce wasn't created too long ago and is still valid (using the exp or expires claim)
The signature of the JWT is valid. This can be done using the public key of the client.
Doing like this could lead to a spaghetti of trust, however. To avoid this, your OAuth server could instead embed a nonce into the app's ID token, or allow the client to request new ones as needed (by performing token exchange e.g.). Then, the API only has to trust the OAuth server, and doesn't need to keep track of the client's public key. If you only have a handful of clients, this won't be hard to mange though.

Oauth flow for google

I am trying to impliment Oauth for my webapplication for google.I am worked upon a POC and it working fine but i have a confusion and not sure how best it can be achieved.
I am using scribe java API for Oauth.
here are the steps i am performing.
Getting request token from Google.
Redirecting user to Google to authenticate them self and authorize my serivice to access his/her few details.
get Access Toekn from google by providing request token and verification code given by google.
Accessing user info once google provide Access token.
now my main confusion is at step no 3, since i am working on a web-application so it will be a 2 step process.
Redirecting user to google
Handling back google redirect.
In order to get an Access token i need to provide same request token which i got at step1 else my request being rejected by the user.
The request token contains 2 things
Toekn -->which is based on the registered application so not an issue
Secret-->This is always being a random string so it should be same when asking for access token
that means i need to store this secret either in my session or some where so that i can access this secret when user is being redirected back to my application.
My confusion is,since in order to save it in session i have to create a unique key and some way to access it in the other action class which will handle Google Redirect back how can i achieve this since at a given time so many user can ask to login using google.
any help in this regard will be much appriciated.
Thanks in advance
When you receive the request token + token secret, use the request token as the unique key of your session to store the token information. After the authorization process, in the callback url, you have access to the request token (it's one of the parameters passed to the callback url). Using this parameter as the session key, you can restore the token information from session, including the token secret, and use it to sign your request for changing the request token for access token. After receiving the access token, a new token secret is returned to you and you can delete the old one from session.
how can i achieve this since at a given time so many user can ask to
login using google
This is not of any problem because for every single user on your site, you are given a different request token.

google hybrid protocol authentication issue

I've been successfully using OAuth1.0+OpenID Hybrid protocol for authentication with Google and thereafter using its services.
However, I am facing an error for a specific user account.
My current flow:
Perform Discovery
redirect user to provider with OpenID and OAuth parameters (like : https://accounts.google.com/o/openid2/auth?https://accounts.google.com/o/openid2/auth?openid.ns=http://specs.openid.net/auth/2.0&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&.....&openid.ns.ext2=http://specs.openid.net/extensions/oauth/1.0&openid.ext2.consumer=mywebsite.com&openid.ext2.scope=https://picasaweb.google.com/data+https://www-opensocial.googleusercontent.com/api/people/+http://www.google.com/m8/feeds/)
Once, user successfully authenticates and approves permission request, application returns back to my specified callbackurl long with a string similar to aforesaid request from which I extract authorization token from "openid.ext2.request_token" and then obtain access token by passing it.
However for a specific user account, instead of passing result as stated above after successful authentication and grant of permission, google redirects to some URL https://accounts.google.com/o/openid2/approval?xsrfsign=AC9jObYAAAAATpF6x6S6Ac7MfHaZ and then back to my application without any parameter in query string.
Same code works fine for other accounts. I'm not able to identify what special can be for one account (except that I created it just last month). As a note, this happens only when I include picasa in scope. If I exclude picasa, it works.
Please help on this.
Was able to fix this issue by adding a request_token request. strangely, it works without having this request for most of the accounts. However for new accounts created I had to explicitly set this parameter in request. Once, this parameter was set, instead of redirecting user to xsrfsign.. URL, I got user details and request token.

Resources