How to purge chrome.identity cache? - api

I am developing a Chrome plugin that uses chrome.identity API. There are two distinct flows, one for authenticated users and another for non-authenticated ones. During testing, the problem I'm facing is, if I authenticate the user calling getAuthToken() and then disconnect the connected app from Google account, the plugin still takes the authenticated flow, because I believe chrome.identity framework caches the authentication token. I need to actually wait for some time for getAuthToken() to "realize" that the authentication has been revoked and then the authentication dialog pops up. Is there any way to forcefully purge the chrome.identity cache?

You could use chrome.identity.removeCachedAuthToken. According to documentation:
Removes an OAuth2 access token from the Identity API's token cache.
You have to pass the token you want removed in the first argument, so if you acquired a token with:
var myToken;
chrome.identity.getAuthToken({interactive:true}, function(token){
if (token) myToken = token;
});
You then use:
chrome.identity.removeCachedAuthToken({token:myToken},function(){
//token was removed from cache
});

Related

Configure Silent Authentication in Open ID Connect

client type: Spa
grant type: implicit or code(pkce)
As a user, I want to be able to get silently authenticated if I have already logged with my identity provider. If not stay on the client side just like a guest user. And if I want to login to the client I should be able to get authenticated manually through the login page.
This has both manual sign-in and automatic sign-in scenarios. How would you handle such cases in Open ID Connect?
By adding the prompt=none in client settings will silently get a new token if user has a valid session. But if not I want the user to be able to manually authenticate through the login page upon his/her wish.
If I set prompt=none this will never have any user interaction such as authentication.
tags: Silent authentication oidc, automatic login, SSO
It is quite a deep subject, and the flow typically works like this:
CLASSIC OIDC SOLUTION
User is redirected for each SPA
If signed in already at the IDP there is no login prompt
OAuth state is stored in local storage (though it is recommended to only store actual tokens in memory)
When an access token expires (or before) do an iframe token renewal with prompt=none
When a new browser tab is opened do an iframe token renewal to get tokens for that tab - to avoid a full redirect
When the user logs out remove OAuth state from local storage
The most widely used library is OIDC Client which will do a lot of the hard work for you. See also my blog post + code sample for how this looks visually.
PROBLEM AREAS
It is worth being aware also that iframe silent renewal does not work by default in the Safari browser in 2020. Some notes on this here.
Alternatively, you can use signinSilent(). I have used it on my login page ngOnInit (since AuthGuard will anyway redirect the user to login, I thought it will be the perfect place in my scenario).
// login.ts
ngOnInit(): void {
this.authService.signinSilent().then(_ => {}).catch(_ => {});
}
// authService
public signinSilent() {
return this.userManager.signinSilent();
}
signinSilent method will return the user object if user already has a valid session with idp. else it will throw an error, probably login_required.

Is it necessary to manually invalidate Facebook Access Token?

I'm building my first app using react-native and expo.
When I log in into my app using Facebook Auth and my personal account, I receive an access token; then I save it locally in the device using SecureStore, provided by expo.
If I try to log out, and then log in another time, I receive a new access token, different from the first one.
But if I try to make a get request, for example just to obtain the name of my facebook account, using the old access token...I can do it!
I wrongly thought that every time the same user try to access into the app using facebook auth, facebook gives the same access token given in the previous session (if it isn't expired or invalidated yet).
So... What I have to do? Just locally override the old token with the new token? Or should I invalidate the old token because of it is still valid (and if so, how could I do this)?
Access Tokens are not valid forever: Basic User and Page Tokens are valid for 2 hours so you do not have to invalidate them on your own. Extended Tokens are valid for 60 days but I assume you do not use those. Just override the Token with the new one, you do not need to worry about old Tokens.
Source: https://developers.facebook.com/docs/facebook-login/access-tokens/#termtokens

Authentication with AzureAD via TestCafe Tests

I'm unable to authenticate / sign-in via AzureAD when running testCafe.
const testrole = Role(
'https://login.microsoftonline.com/',
async t => {
await t
.typeText(Selector('input').withAttribute('type', 'email'), *******)
.click(Selector('#idSIButton9'))
.typeText(Selector('input').withAttribute('type', 'password'), ********)
.click(Selector('#idSIButton9'));
},
{ preserveUrl: true }
);
The above steps work fine, however after entering the password I get a message saying:
"Unable to sign in to Outlook account, Error: AADSTS900561: The endpoint only accepts POST requests. Received a GET request."
From my initial search, it seems like something to do with 3rd party cookies on the browser. However, I'm unable to find a solution at this time.
Any idea how I get around this issue?
The Azure AD product team has always reminded me that it is a bad idea to try to automate sign in like that.
They will probably detect that you are a bot and start blocking your requests, even if you succeed.
Instead, to acquire access tokens you need to use either the client credentials flow (for app-only tokens) or the resource owner password credentials flow (for delegated user tokens).
Client credentials flow: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
ROPC flow: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc
You have to take good care to secure the credentials used for testing.
And use a test tenant if possible.

Identity server 4 + asp.net core: logout on multiple tabs of browser

Currently, I am using ID4, asp.net core and angular 2. Everything works well but I am facing one issue, when we open many tabs on browser. Then, we logout on one tab but other tabs still keep token and call API successfully. Can we force or validate token and return to login page on all tabs?
My code to sign out on server
await _signInManager.SignOutAsync();
HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
var logout = await _interaction.GetLogoutContextAsync(model.LogoutId);
return Redirect(logout?.PostLogoutRedirectUri);
Thanks,
You cannot revoke JWTs: once issued they are valid until they expire. So if you are using Identity Server to issue JWT access tokens then you what you ask isn't possible, so long as something has the JWT (and it hasn't expired) then it can be used to gain access to your resources.
Instead you could change to using Reference Tokens, which aren't self-contained and upon each use will cause the receiving resource (such as your API) to verify it with the IdSvr. One of the effects of this is that you can then revoke your access tokens, which means it doesn't matter if other tabs think they have the access token because when they try and use it the IdSvr will know that they are no longer valid. If you go down this route you will now need to persist your access tokens, and each protected call to your client will involve it doing a back-channel communication to your IdSvr.

Web API 2, OWIN Authentication, SignOut doesn't logout

I'm doing some research for work with a view to using Bearer tokens as an authentication mechanism (i.e. AngularJS UI, authenticates via OWIN in a Web API [2] project).
I have the login working fine, role information and all that is fine, but I cannot get the token to logout.
My startup configuration is this:
OAuthOptions = new OAuthAuthorizationServerOptions() {
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan = SESSION_TIMEOUT,
AllowInsecureHttp = true
};
And my logout action is simply this:
public HttpResponseMessage Logout() {
var authentication = HttpContext.Current.GetOwinContext().Authentication;
authentication.SignOut(DefaultAuthenticationTypes.ExternalBearer);
return new HttpResponseMessage(HttpStatusCode.OK);
}
I've left all the authentication stuff out for brevity, but to confirm I am using ExternalBearer when setting up the token.
In my UI I'm storing the token in local storage (no cookies are involved here, which is a deliberate design decision). So I have a logout button on my UI, the Logout action is hit and the code runs fine.
However if I subsequently hit the an action on the API which requires authorisation, the request still goes through (i.e. the user is still authenticated even though they should have been signed out.
Either I'm missing something really obvious (wouldn't be the first time ;-) or there's something more fundamental going on here - finally I'm pinging #leastprivilege as I know this is their area.
Any help or insight would be gratefully received.
Only thing I can think of is that the token is stateless on the server/API side and hence can't be expired or signed out.
If that is the case I guess I could either:
a) Add a refresh token which creates a new token that expires in the past - would this even work? - actually cancel that, it would issue a new token ... the old one would still be valid
b) Store the bearer token in the database and check each time, removing the token on logout (naturally salted, hashed, etc). However this is just bringing us back to having a stateful server.
c) I can (and will) be removing the token from local storage when someone explicitly logs out, however the token is still technically valid if a baddy can intercept the token. Naturally all the above will be over SSL anyway, which should inhibit the bad guys/girls.
d) Perhaps this is why lots of people are storing the Bearer token in a cookie (as a storage mechanism) so once you logout as least the cookie will be removed on the next refresh.
Sorry the above is a bit of a brain dump, just wanting to pre-empt any questions
Since OAuth is not an authentication protocol, there is no notion of signout. Delete the access token on the client - that's all you can do.
If you want to invalidate the token on the server side, add a unique id to it and keep track in your service - you would need to manually build something like that.
I have a beautiful solution here: http://www.nakov.com/blog/2014/12/22/webapi-owin-identity-custom-login-service/. It is custom user session implementation for Web API OAuth bearer token authorization based on OWIN and the standard ASP.NET Identity (Microsoft.AspNet.Identity.EntityFramework). It works as most people may expect:
Web API sessions die after 30 minutes of inactivity.
Session’s life is extended at each authorized HTTP request with additional 30 minutes.
Logout works correctly: after logout the bearer access_token becomes invalid (its is revoked).
Full working source code is available at GitHub: https://github.com/SoftUni/SPA-with-AngularJS/tree/master/Ads-REST-Services
This question has been here for ages (and answered too), but I only wanted to chime in my thoughts.
I would do similar to your (C) option, but use a shorter expiry on the bearer access token something like 10 or 20 minutes, so that when you have logged out and deleted the token on the client, although technically the token is still valid, the bad man will have only the remainder of the expiry time to play with your valid token.
In practice, I would use this together with a long-lived refresh token, so that I can get a new bearer token if it expires and want to continue interacting with the API resources, without having to authenticate again.
As long as I know the bearer token lives in the client side so I don't think that you need a server side "logout" function. Just remove the token from the client local storage should log you out.