IdentityServer userinfo endpoint not requested after silent renew - javascript

we currently facing the problem, that the silent renew is going to not working after about 30min. We were able to determine that the SubjectId is missing on IS4.
When looking into the network tab in chrome for the client requests, the following order is visible:
authentication request
silent renew request
user info request
network requests
Step three is missing before the next authentication request and due to that the SubjectId, I guess.
Our access-token lifetime is 1 h, identity-token lifetime is 5 min. For testing purpose we set the silent renew to trigger every 4 min.
We are using the oidc-client-js#1.4.1 in combination with the redux-oidc lib.
Is there anything we forget in our configuration on client / server side?
Thanks a lot.

The problem was not located on client side. The cookie for the user was expiring on the back end side.
link to github with solution by the creator

i think you have to listen to UserLoaded events thus you will load the new user after a silent refresh request
this._userManager.events.addUserLoaded(args => {
this._userManager.getUser().then(user => {
this._user = user;
});
});
getUser will be called after every silent refresh call to get the new user

Related

Is there a way to detect that the taken Firebase token, Is it taken from network call or from cache?

I'm working with Firebase Message in Web.
According to Firebase about messaging.getToken():
Initially it makes a network call once retrieved. subsequent calls to
getToken will return from cache.
But we see in the code below that every time the page is loaded, it takes the token from messaging.getToken() function (either from the network or from
the cache) and each time it sends to the server (by sendTokenToServer()).
messaging.getToken().then(function(currentToken) {
if (currentToken) {
sendTokenToServer(currentToken);
updateUIForPushEnabled(currentToken);t
} else {
// Show permission request.
console.log('No Instance ID token available. Request permission to generate one.');
// Show permission UI.
updateUIForPushPermissionRequired();
setTokenSentToServer(false);
}
Link of Code in Github
I also want to use the topic. subscribing the Token to topic every time, is not optimal.
In that case, I must subscribe token to topic, Every time the page is loaded.
Is there a way to detect that the taken token, Is it taken from network call or from cache?
If the taken token is from cache, I will not send the token to the server and also do not subscribe to the topic (Because it's done first.)
If you want to know of the token is new or not, you will have to compare its value against a token that you previously cached yourself in local storage. The API will not give you any indication.
It's not really that bad to just send it to the server every time anyway.

How to redirect web application flow to specific page when session ends?

I have a web application developed on AngularJS / Javascript, back-end is Java / Spring. I have an issue related to session management for my web application.
I have set the session timeout using the web.xml session-timeout parameter in session-config like below,
<session-config>
<session-timeout>1</session-timeout>
</session-config>
Now after 1 minute, the session times out. I have a scenario where I need to redirect my web application flow to login page after the session has timed out.
Scenario 1 : If I click on any link / button which needs to load a new page, it automatically detects that the session has timed out and it redirects the application to login page. THIS WORKS FINE.
Scenario 2 : BUT if the page contains any drop-downs that I select, the application doesn't redirect to login page. THIS IS THE ISSUE.
What happens generally is when I chose any value from drop-down, it makes a rest call to back-end and fetch the data needed to fill in the values on the page. Now if the session has ended after a minute, and if I select the drop-down, it doesn't make any call to back-end as the session is over.
Now, in this scenario what should be done to make sure that even when I chose the drop-down and if the session is over, it will detect it somehow and redirect the application to login page. Is there a way using angular JS or javascript to check if the session is still alive when I chose the drop-down value and can redirect the flow as per need?
Considering the fact that when I chose the drop-down the flow doesn't go to back-end, I guess I might need to handle this redirection at client side only (front-end) instead of back-end. Not sure how to do that though.
Any help would be appreciated.
You can make use of http intercetor to help you here. Basically, interceptor will be executed every time you make a request, make an error while making a request, when you response or when you get error in response. Depending upon response status, you can redirect the control to an error page.
app.factory('CustomHttpInterceptor',[ '$q' , '$location', function( $q , $location, TimeoutBroadCaster ){
return{
request: function(config) {
return config;
},
requestError: function(config) {
return config;
},
response: function(res) {
return res;
},
responseError: function(res) {
if(res.status != 200){
$location.path( 'timed-out' );
}
return res;
}
}
}
]);
And then in config method at application start up, you push this interceptor in queue with
$httpProvider.interceptors.push('CustomHttpInterceptor');
To make things easier, at server end, you can come up with some custom error status which can help you determine if session had timed out and write check specifically for that condition.

Callback, which fires on every user action

I would like to implement a timeout functionality in an AngularJS web app. Whenever a user does anything, a callback sets the timer to 10 minutes. When this timer expires on the client-side, a timeout request is sent to the server.
How can I implement a callback which fires from every user action? Maybe register onclick and onkeydown listener on the whole page/window?
According to the angular docs for $rootScope:
If you want to be notified whenever $digest() is called, you can
register a watchExpression function with $watch() with no listener.
I am not sure if $digest is called on every user action but it might be a good place to start.
FYI - How I implement a User time-out is as follows:
Authenticate user via server side API
Have API store the user in a cache with sliding expiration and pass back a session token
Have each secured API end-point require a session token and use this to fetch the User from the cache thus resetting the expiration timer.
If the User does not exist in the cache return a 403 forbidden error which your client code handles, presumably by sending the user back to login page. Actually I return a custom 403 that has a specific 'User Timeout' code and message so my client can handle the time-out gracefully.
This should work fine for most Single Page Apps because pretty much anything the user does causes a state change and most state changes involve a call to the server to fetch or save stuff. It misses out on minor user actions but in I have found that the real world use of this technique has sufficient resolution to be effective.
Looks like hackedbychinese.github.io/ng-idle does what I need

Oauth2 Implicit Flow with single-page-app refreshing access tokens

I am using Thinktecture AuthorizationServer (AS) and it is working great.
I would like to write a native javascript single page app which can call a WebAPI directly, however implicit flow does not provide a refresh token.
If an AJAX call is made, if the token has expired the API will send a redirect to the login page, since the data is using dynamic popups it will this will interrupt the user.
How does Facebook or Stackoverflow do this and still allow the javascript running on the page to call the APIs?
Proposed Solution
Does the below scenario sound sensible (assuming this can be done with iframes):
My SPA directs me to the AS and I obtain a token by Implicit Flow. Within AS I click allow Read data scope, and click Remember decision, then Allow button.
Since I have clicked Remember decision button, whenever I hit AS for a token, a new token is passed back automatically without me needing to sign in ( I can see FedAuth cookie which is remembering my decision and believe this is enabling this to just work).
With my SPA (untrusted app), I don't have a refresh-token only an access token. So instead I:
Ensure user has logged in and clicked remember decision (otherwise iframe wont work)
Call WebAPI, if 401 response try and get a new token by the below steps...
Have a hidden iframe on the page, which I will set the URL to get a new access-token from the Authorisation Server.
Get the new token from the iframe's hash-fragment, then store this in the SPA and use for all future WebAPI requests.
I guess I would still be in trouble if the FedAuth cookie is stolen.
Any standard or recommended way for the above scenario?
I understand that your problem is that the user will experience an interruption when the access token has expired, by a redirection to the login page of the authorization server. But I don't think you can and should get around this, at least, when using the implicit grant.
As I'm sure you already know, the implicit grant should be used by consumers that can NOT keep their credentials secret. Because of this, the access token that is issued by an authorization server should have a limited ttl. For instance google invalidates their access token in 3600 sec. Of course you can increase the ttl, but it should never become a long lived token.
Also something to note is that in my opinion the user interruption is very minimal, i.e if implemented correctly, the user will only have to authenticate once with the authorization server. After doing that (for example the first time when also authorizing the application access to whatever resources the user controls) a session will be established (either cookie- or token based) and when the access token of the consumer (web app using implicit grant) expires, the user will be notified that the token has expired and re authentication with the authorization server is required. But because a session already has been established, the user will be immediately redirected back to the web app.
If however this is not what you want, you should, in my opinion, consider using the authorization code grant, instead of doing complicated stuff with iframes.
In that case you need a server side web application because then you can keep your credentials secret and use refresh tokens.
Sounds like you need to queue requests in the event that an access token expires. This is more or less how Facebook and Google do it. A simple way using Angular would be to add a HTTP Interceptor and check for HTTP401 responses. If one is returned, you re-authenticate and queue any requests that come in after until the authentication request has completed (i.e. a promise). Once that's done, you can then process the outstanding queue with the newly returned access token from your authentication request using your refresh token.
Happy Coding.
Not sure if I understand your question but,
I would like to write a native javascript single page app which can call a WebAPI directly, however implicit flow does not provide a refresh token.
Summarize facts,
refresh token is sometimes used to be a part of A: Authorization Grant
https://www.rfc-editor.org/rfc/rfc6749#section-1.5
and as you said in implicit flow you dont get back refresh token, but only in Authorization Grant part
https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2
so you can get back refresh token when issuing access token (refresh tokens are always optional)
https://www.rfc-editor.org/rfc/rfc6749#section-5.1
With my SPA (untrusted app), I don't have a refresh-token only an
access token. So instead I:
Ensure user has logged in and clicked remember decision (otherwise
iframe wont work)
Call WebAPI, if 401 response try and get a new
token by the below steps...
Have a hidden iframe on the page, which
I will set the URL to get a new access-token from the Authorisation
Server.
Get the new token from the iframe's hash-fragment, then
store this in the SPA and use for all future WebAPI requests.
SPA(you) have no idea if user selected remember decision. Its in AS direction and should be complete blackbox. Skip this step.
You can try to use access token and wait for result, always.
If access token has expired and you dont have refresh token, you still can create hidden iframe and and try to get new access token.
Lets assume your AS provide option to remember decision and wont change it in future, then: your iframe will get new access token without user interaction, then you will get result back in some unknown time limit.
Result can be checked by setInterval for read specific cookie or iframe postmessage.
If you dont get back data in time limit, then one from following scenarios occured:
lag, AS is slow, connection is slow or time limit is too tight
user didnt select remember decision
In this case:
show iframe with login
I consider scenario above as good practise if AS doesnt provide refresh tokens, but I also guess every AS like that wont provide remember option as well.
StackOverflow <---> Google scenario (I can only guess)
User login, authorization request occured
User logs in, SO gets access token
SO tries to use access token
SO gets back result + refresh token
SO saves refresh token
SO has permanent access to users Google account
In Google o-Auth , the access token will only be valid for 1 hour, so you need to programmatically update your access token in each one hour, simple you can create web api to do so,you need to have a refresh token, and also that refresh token will not be expired , using c# code, I have done this.
if (dateTimeDiff > 55)
{
var request = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/oauth2/v3/token");
var postData = "refresh_token=your refresh token";
postData += "&client_id=your client id";
postData += "&client_secret=your client secrent";
postData += "&grant_type=refresh_token";
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
request.UseDefaultCredentials = true;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
}
you need to save the last updated date time of the access token somewhere(say in database), so that , whenever you have to make a request , so you can subtract that with current date time , if it is more than 60 minutes , you need to call the webapi to get new token .

Is there anyway in flex to get the status of server?

we have an application where button click in flex side restarts the server and makes the client logged out. once after logout, If user logs in it gives error since the server is not up by the time. In our scenario the server takes time to restart because of the stuff(like back up). I want the user to be notified of the webserver status if he tries to log in.
is there any way to monitor the status of server in Flex side. or Will javascript help in finding whether the server is up or not?.
Also I tried redirecting to html page using external interface but I am not sure how to automatically redirect it again to the swf file when the server becomes active.the server downtime is not known(may be 2 or 5 or 10 minutes.)
So what would be the best approach.Any help would be of greatly appreciated.
Using URLLoader you can try to download a file on the server and listen to ioError or httpStatus.
private var testLoader:URLLoader;
private var testRequest:URLRequest;
...
testRequest = new URLRequest("http://server/testFile");
testLoader = new URLLoader(request);
testLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onStatus);
private function onStatus(HTTPStatusEvent:event):void
{
//test the status, if the server is up, reconnect, else...
testLoader.load(testRequest);
}
Interesting problem. When you mean restart, do you mean just a specific service like Apache or like an actual reboot of the server? I ask because it would mean different scenarios. I'm not exactly sure what you're doing, but I'll assume that you're rebooting the server.
One of the problems here is that the client logs out, which is something we do not want. What I would do is have a second server which it's sole purpose would be authentication and giving status on the other server. This is a 'man in the middle' approach where this server doesn't log you out, but all calls are redirected to the other server.
From the Flex side, you can have it calls the 'man in the middle' to see what's the status. Depending on the technology you're using (polling vs pushing), you can get the data needed and show the user the status.

Categories

Resources