In my application I use web services to get required information. To actually use this services you have to login first, you get your token - encrypted password, afterwards this token is attached to SOAP requests to identify current user. The thing is, when you do not use service for 15 minutes, your token changes and when you are trying to obtain another bunch of information from the server it denies old token. As a result app do not get required information and throws a heap of errors.
How to send user (load Login.axm) to Login page when token has been changed?
Thank you, Shay Shmeltzer for your answer.
How I solved this problem:
1) First I read how does sessions work in my particular case. I used stateless session which means -
A new session is opened for an initial request and the session remains
open for subsequent requests. Relogin occurs automatically
(transparent to the user) if the session is closed. UsernameToken and
PasswordText must be included as SOAP headers in the initial request
to open a stateless session.
Stateless session management is the best method to use for high-load
Web service applications. Using Stateless mode, the application
provides the username and password only once, that is for the initial
request. A session is opened on the server and is dedicated for this
user.
In the response Siebel Business Applications return the SessionToken,
which is an encrypted string containing the information about
username, password, and timestamp. For subsequent requests the
application must use the SessionToken to reuse the session.
For security reasons SessionTokens are regenerated for each response.
The application must provide the last received SessionToken for the
next request.
The SessionToken-Siebel session map is maintained in the Siebel Web
Server Extension (SWSE); based on the SessionToken value SWSE sends
the request to the correct Siebel session (task).
Although the session is persistent, authentication happens for each
request (SWSE decrypts the UserName and Password from the
SessionToken).
the main problem was :
NOTE: Reconnecting or automatic logging in again will only happen if
the token has not timed out. If it times out, then the user must
manually log in again. Token timeout must be greater than or equal to
session timeout. For more information on session token timeout, see
Session and Session Token Timeout-Related Parameters.
in my case standard session token live time was 15 minutes.
That is why I included counter in my code and checked it before each request. If counter time > 15 minutes, I sent log in request to the server to get new session token. The reason, I did not change current page to log in page straight away after the counter exceeds 15 minutes is: place in code, where I check counter is already initiated by the bindings to get required value to render it, so if your token has expired you will get a heap of errors. That is why firstly I renew the session sending log in request, get active session token and put it into the last request which is requested by binding. After app renders page without any errors, it shows pop up message "Session has expired" and goes to log in page.
You can programmatically set the soap header being sent to your SOAP service from ADF Mobile - http://docs.oracle.com/cd/E37975_01/doc.111240/e24475/amxwebservices.htm#CHDIBIIE
Related
I have a grails server and an iOS client that communicate over HTTPS via POST messages. I'm using PersistentTokenBasedRememberMeServices to ensure that the user doesn't have to enter his password all the time. This doesn't seem to work as the session is lost continuously and the user has to login again. The server logs show that a CookieTheftException has occurred with message "Invalid remember-me token (Series/token) mismatch".
Not all server actions require a logged in user. Some can be accessed anonymously and this may be the root of the problem. When the user accesses restricted server actions, the session is maintained, but not when accessing unrestricted actions.
Here's my config in Config.groovy:
grails.plugins.springsecurity.rememberMe.cookieName = 'SomeRememberMeName'
grails.plugins.springsecurity.rememberMe.persistent = true
grails.plugins.springsecurity.rememberMe.alwaysRemember = true
grails.plugins.springsecurity.rememberMe.persistentToken.domainClassName = 'com.myapp.PersistentLogin'
grails.plugins.springsecurity.rememberMe.tokenValiditySeconds=31*24*60*60
I added some traces in the iOS client and noticed a couple of things. First of all the JSESSIONID cookie doesn't have an expiration time, which means it isn't saved in the client like the rememberMe cookie. Can I force it to have an expiration time or is that even a good idea? Secondly I noticed that sometimes the rememberMe cookie that I receive from the server is empty. That may be just because a CookieTheftException was thrown.
Since all of the post message bodies are encrypted with 256-bit AES, I'm not really worried about cookie theft at this time. I just need to get this to work.
I tried adding the following to my config to ensure that the session would be always updated even when accessing unrestricted actions:
grails.plugins.springsecurity.useSessionFixationPrevention = true
grails.plugins.springsecurity.SessionFixationPrevention.migrate = true
grails.plugins.springsecurity.SessionFixationPrevention.alwaysCreateSession = true
I don't even know what these all mean. I just liked the "alwaysCreateSession" part and figured that I need to enable session fixation prevention in order for that setting to have any effect. Will it still always create a session if I set useSessionFixationPrevention to false?
Any help is appreciated.
If you are using PersistentTokenBasedRememberMeServices, your "remember me" token will change after every HTTP request.
Unfortunately that means that requests will only authenticate if your browser makes exactly one request at a time, and browsers often don't do that. If there are 4 few images on a page, the browser will send out 4 simultaneous requests, each with the same "remember me" token. Only the first request will authenticate, because after Spring Security processes the first request, it changes the token. When Spring Security tries to process the next request, it throws a CookieTheftException.
That's the typical scenerio for the CookieTheftException when using PersistentTokenBasedRememberMeServices.
Here's a link that explains some things you can do about it: Grails Cookie Theft Exceptions
There's also an open issue with the Grails Spring Security Core plugin that discusses this problem: Remember me functionality fails intermittently with CookieTheftException: Invalid remember-me token
The JSESSIONID stuff is probably a red herring. If you're using PersistentTokenBasedRememberMeServices, your authentication won't need a session.
When a browser client successfully submits the username/email and password to the server and the next request the client retrives data from the server how is the client identified being successfully authenticated already?
I found this info:
"After the user enters credentials, the browser automatically sends them on subsequent requests to the same domain, for the duration of the session."
From where does the browser take the credentials for each subsequent request?
Do I have to actively save the credentials somewhere? How is the magic happening?
Once the user's credentials have been authenticated by the server, the server returns an authorization token (commonly called auth token which is a long string made up of characters and numbers) which identify that the user has been authenticated and is valid. Every time, the user sends in his request, the request data will also contain this auth token (either as a cookie or added in to the request itself) which lets the server know that the client is valid. Because of this, the request is authenticated each time but not by using the actual username/password credentials.
Based on requirements, the auth token may be set to expire after a certain period (if there is not activity such as in banking applications).
I can redirect a user to home page upon session logout.. this was very simple. However, if an user had logged into the app and had the page open, even on session time out, he is able to perform all the functions(this is bad).
The redirect does not happen until the page is refreshed, or submitted to the server... there are some update functions that could be done by the user even if he is not currently logged in... I have done a lot of research but unable to fix this solution. I also found this thread but it seems to have no proper answer:
Spring Security 3.1 - Automatically redirect to login page when session-timeout occurs
For example, most of the banking sites log you out after a time out.. they do not wait until you come back and then submit a request before you are redirected to home page.
HTTP is stateless. To achieve some form of state the server can maintain a session for each user by giving them a session id on their first request. The user would have to resend that session id on each future request to identify that the other requests happen within the same session.
Because the session is maintained by the server, there is no way to notify the client that the session has timed out.
Instead, if the user makes a new request when the session is timed out, their session ID is no longer good and therefore you can take a particular action like redirect them to login page.
Assuming nothing works out. You may want to consider below mentioned approches:
Approach 1:
Create a cookie on browser and have encrypted timestamp in it that will contain last visited/request timestamp from browser, for each request first get get this cookie value and compare with the pre-defined session out time, if session-out time reached then redirect user to error page else serve the request. On logout delete the cookie.
Why encrypted value for timestamp: if somehow user gets to know about cookie used for session timeout then (s)he can change this value in browser and keep on sending this request.
Approach 2:
You can also achieve this by making an entry in your database for every logged-in user and updating timestamp in this database for each request. For each incoming request get this timestamp from database and compare it with pre-defined value for timeout and handle accordingly. On logout delete the entry.
In both the approaches explicitly perform response.redirect("errorPageUrl");
I have this web app written in AngularJs that uses cookies to authenticate the requests in a REST API.
Once the user logs in, the cookie is received and saved in the browser and all subsequent requests send the cookie along to the server. There is a 'User' service/object that saves the isLoggedIn and username values (for UI display/flow). Now, if I refresh the 'index' page, the app restarts. This means that my 'User' object will be cleared. I can check the existence of the cookie and, if it exists, I can re-set the User.isLoggeIn as true and go from there, but I still need to get the username, id, etc. So, my question is: should I create some sort of 'ping' endpoint in the API to verify if a cookie is valid? And if so, the API would send me back the user id and username... OR should I persist the user data in LocalStorage (or some similar cross-browser thing) and just assume the user is logged if the cookie exists? Any other subsequent requests to pages that need authentication would be automatically verified. So, this question really only applies to the scenario where the user refreshes the index page - hence, restarting the web app. I want to know the user data because I want to show a 'user homepage' instead of the 'public homepage'.
What do you think?
You should depend on the server for this. Creating something like GetCurrentUser method on the server. If the user is logged on this returns all the properties of the user.
You should even use this server api to get the user data after authentication completes. So the authentication become two step process first the user is authenticated, on success another call is made to server to get current users details.
Using client side local storage for this would not be ideal because you need to do lot of book keeping, in terms of cleaning the logged in user on log out or session expiration.
Also cookies from server would have expiration times an all, and making decision just based on cookie existing on local storage may not be optimal approach.
Looking at the OWASP Session Management Cheat Sheet, every time a session expires, must a user go through the same Pre-Auth --> Auth --> ... steps to make a new session?
For example, if a session expires and the web app requires authentication, will the user have to log back into the web app before getting a new session?
Sessions are maintained with cookies.
Http is a stateless protocol. Every request to server works in isolation. No request has any information about previous request.
Say a user named A logs in to the site. This site works with session and sets session data for a user. Internally the server creates some value and associates with a particular user. A value 12345 is computed and associated with user A. The server decides to give this value's name as sessionId. It sends sessionId in the cookie and this cookie will be stored on the user's browser. Next time the user A makes a request this cookie will be sent to server. Server reads for cookie sessionId, and finds it. Then it sees with what user is the value in this cookie i.e 12345 is associated. It finds that this value is associated with user A and so its the user A, who is making the request.
Say this cookie expires, can be for various reasons. Either user deletes the cookie on his end. Or after certain days, server cleans this association between user and the session. In that case server will not be able to know who is the user making the request. And hence the entire flow of login by user, seesion generation will have to take place.
So, yes, if a session expires and the web app requires authentication, user will have to login again
Yes, the user has to log in again. Also, it's important that a new session gets a new session id, as an attacker could have gained the session id. If you re-authenticate the same session id, the attacker would gain access as well. See session fixation attack.
Depending on the safety requirements, you might also have to implement a maximum time to life for every session. Usually an attacker would take over a session and try to keep it alive as long as possible. Expiring the session after a certain amount of time, even if it is active, is an effective way to ensure that attackers can only have access for limited time.