actually I'm just starting to play around spring mvc in webapp and I have tumble across spring security which handles the authentication and session. My question is how does it handles session and can I create my own session id reference for spring security to use. I did use spring security but somewhat I feel blinded by it's process. Another thing is that can I add my own session service that I can control more if its implementable can you give me an insight in where can I start.. Furthermore I'm sorry for my English and if it is a duplicate question, though I think that topics concerning with spring security doesn't satisfy what i had in mind... Thanks for the feedback...
Spring Security handles sessions nicely on its own. If you make a request, it'll append the session id in the response. You can read it and store it if you want to, so you can send it back as a cookie. We use this method with our Android application, because it does not handle it automatically as web browsers do.
If you're making a web application, the browser will store and send back the session id, so you don't have to worry about it.
It seems that spring security implementation is not tied to HTTP session directly, take a look at this package org.springframework.security.core.session, There is SessionCreationEvent, SessionDestroyedEvent and SessionInformation. SessionInformation assumes that you have a String ID for the session but nothing else.
Now of you take a look at SessionRegistryImpl the java doc says you have to add org.springframework.security.web.session.HttpSessionEventPublisher to your web.xml for the registry to be notified of the session events. So if you want to provide your own implementation of session management just replace HttpSessionEventPublisher with your own implementation.
Related
I have been following the example in this tutorial: https://spring.io/blog/2015/01/28/the-api-gateway-pattern-angular-js-and-spring-security-part-iv
In brief:
I have a server called UI that has some html and angular js.
I have a server called resource that has a RestController who is serving the content from a DB. All the calls must be authenticated.
The UI server has a login page which works with spring http basic login and creates a spring session that is stored in a Redis server and it is shared to the resource server. When i have some dummy users in memory authentication everything works fine.
The question is:
I want my UI server to be able to perform a login with real users, that exist in the DB. The UI server should not have any DB related code (not knowing its existence) but it should call a REST service in the resource server. The only way i was thinking (but is sounds wrong to me) is to implement a userDetailsService bean in the UI and the loadUserByUsername method should call a rest service from the resource server (e.g. /getUser). The rest service should return all the user details including credentials and roles for the given username. However, to my understanding, this service cannot be secured (for the call to be successful) which compromises the entire security.
I am open to all suggestions and recommendations. Bare in mind this is my first attempt to work with Spring.
Thank you in advance,
Nicolas
In case that someone is interested how i tackled this..
I decided to do the prudent thing and study spring security.. :)
My answer is to use a custom AuthenicationProvider in my UI server, which will call an unprotected rest login service in the resource server, which in turn validate the user against the DB.
If the response is successful (e.g. a user object could be returned with username, password, roles) then i will create a UsernamePasswordAuthenticationToken object out of it and return it.
If the response is NOT successful (e.g. return object was null or an exception was thrown) then i will either return null or throw an AuthenticationException, it depends on how Spring behaves... I haven't reached that part of studying yet..
http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#tech-intro-authentication
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements
Features
Comprehensive and extensible support for both Authentication and Authorization
Protection against attacks like session fixation, clickjacking, cross site request forgery, etc
Servlet API integration
Optional integration with Spring Web MVC
I am learning Spring and trying to implement Springs Security. I am not able to understand how it works. I read tutorials from which I understood the following:
we have to configure web.xml for delegating proxy and pattern
we need to add intercepts to dispatcher-servlet.xml
When request is made it triggers intercepts but after that I am unable to understand how it works. It would be helpful if somebody could provide a list of steps to be followed. I am using Hibernate and Spring (both with annotations), I want to authenticate users using Hibernate.
A detailed article can be found here: Code Project Or a tutorial with MVC and Spring Security here.
I tried to illustrate the process a little bit:
The user sends a HTTP-Request to the server
The server processes the request according to the web.xml
The web.xml contains a filter (AKA interceptor) and passes the request through this filter.
Because the user is unknown/not authenticated, Spring Security does its best to get more details.Depending on the config, it
sends an HTTP header, so that a login popup pops up in the browser (client side).
redirects to a form where you can enter username and password.
does a lot of hidden interaction between server and browser to guarantee a "Single-Sign-On" (SSO)
Except for SSO the user enters her/his/its credentials and create an additional request.
Spring Security realizes the login attempt and authenticates the user against a
file with user and passwords
a built-in XML structure in a spring config file
a database
an LDAP
When the access is granted, it assignes the necessary roles...
...and redirects to hard-coded "home page". (Spring Security let's you adjust this behaviour.)
In your application you can check the authorization for certain actions
.....
The user clicks on "logout" or the session expires. With the next request the process starts again.
Annotations
I found a tutorial here (Link).
I understood/assume the following facts:
The filters still must be defined in the web.xml.
You can annotate your classes/methods with
#Controller (API)
#Secured (API)
#RequestMapping (API)
I admit that I only gave you a rough overview, because your question is not that specific.
Please let me know what you want to learn in detail (re-recognize users, authenticate against different resources, do a SSO, create a secured area on your webpage,...)
Spring uses a dispatcher servlet for delegating the request. Spring security filters the request and checks if a valid security context is established. If so the request is passed to the dispatcher and it passes the request forward to the corresponding controller. If no security context is established, Spring security intercepts the request which means he could manipulate the request before the diespatcher servlet could process it. During this interception the request dispatcher (Servlet Specification) will be assigned to forward the request to a login page.
I think you don't have to bother with xml anymore. Now you can use Spring Boot + annotation based configuration. One of the best tutorial I found is this one: A good spring security tutorial
There are some good step-by-step tutorials on how to integrate spring security. For example:
For Java config: http://jtuts.com/2016/03/03/spring-security-login-form-integration-example-with-java-configuration/
For XML config: http://jtuts.com/2016/03/02/spring-security-login-form-integration-example-with-xml-configuration/
We are planning on developing a layer of REST services to expose services hosted on a legacy system. These services will be used by a classic web application and native mobile phone applications.
This legacy system is secured in such a way that an initial username + password authentication is required (a process that can take 5 to 10 seconds). After the initial authentication, a time-constrained token is returned. This token must then be included in all further requests or else requests will be rejected.
Due to a security requirement, the legacy security token cannot be returned outside of the REST service layer. This means that the REST service layer needs to keep this token in some form of user session, or else the expensive username + password authentication process would need to be repeated for every call to the legacy system.
The REST service layer will be implemented using a Java 6 + Spring 3 + Spring Security 3 stack. At first sight, it looks like this setup will run fine: Spring-based REST services will be secured using a rather standard Spring Security configuration, the legacy security token will be stored in the user's HTTP session and every call will retrieve this token using the user's session and send it to the legacy system.
But there lies the question: how will REST clients send the necessary data so that the user's HTTP session is retrieved properly? This is normally done transparently by the web browser using the JSESSIONID cookie, but no browser is involved in this process. Sure, REST clients could add cookie management to their code, but is this an easy task for all Spring RestTemplate, iPhone, BlackBerry and Android clients?
The alternative would be to bypass the HTTP session at the REST service layer and use some other form of user session, maybe using a database, that would be identified using some key that would be sent by REST clients through a HTTP header or simple request query. The question then becomes, how can Spring Security be configured to use this alternative session mechanism instead of the standard Servlet HttpSession?
Surely I am not the first dealing with this situation. What am I missing?
Thanks!
There's nothing magical about cookies. They're just strings in HTTP headers. Any decent client API can handle them, although many require explicit configuration to enable cookie processing.
An alternative to using cookies is to put the JSESSIONID into the URL. I don't know anything about spring-security, but it seems that that's actually the default for at least some types of URL requests, unless disable-url-rewriting is explicitly set to true . This can be considered a security weakness, though.
Unfortunately authentication is highly problematic -- a bit of a blind spot in terms of web standards and browser implementations. You are right that cookies are not considered "RESTful" but purists, but even on fully-featured browsers avoiding takes quite a bit of hackery, as described in this article: Rest based authentication.
Unfortunately I haven't done any mobile development, so I can't suggest what the best compromise is. You might want to start by checking what authentication models each of your targetted platforms does support. In particular, two main options are:
HTTP authentication (ideally "digest", not "basic")
Cookies
One possibility would be to provide both options. Obviously not ideal from a technical or security point of view, but could have merits in terms of usability.
What's the best (most secure) way of implementing session handling in a web server? I'd like to add that, but don't know how to implement it really. Is cookies a "must" for session handling? (To be able to identify which session)
The session handling isn't really your concern. It is handled by the HttpSession class (read the description in the javadoc!), which you can obtain by calling request.getSession().
It works in two ways (no need for you to do anything to support them):
using a session cookie (if cookies are allowed)
using url-rewriting - appending the session id (JSESSIONID) to the URL.
(Note: it is actually handled by the servlet container (Tomcat, jetty, etc) which provides an implementation of HttpSession)
Assuming that you're talking about a servlet container, then session handling comes backed in. See the relevant part of if the JavaEE tutorial. It covers the session API, as well as how sessions are tracked (cookie or URL rewriting).
Session handling is handled by the web container. If you want safety from prying eyes, use https (enforced in web.xml).
What you might be interested in also, is how the user identifies himself to the web container. Several options exist, where the most secure is the client uses a web browser with a digital certificate. That is quite tedious, but very secure :)
I'm working on an existing j2ee app and am required to remove some vendor specific method calls from the code.
The daos behind a session facade make calls into the ejb container to get the user's id and password - in order to connect to the database. The user id and password part of the initialContext used to connect to the server.
I am able to get the userid using sessionContext.getCallerPrincipal()
Is there anyway to get to the SECURITY_CREDENTIALS used on the server connection or, is there a way to pass information from the server connection into the ejbs (they are all stateless session beans).
This is a large app with both a rich-client and web front end, and in a perfect world I'd be happy to go back and re-architect the entire solution to use J2EE security etc - but unfortunately, that is not realistic.
I can't give you a generic solution, but this is what has worked for us. We have the app server connect to LDAP as a specific user that has the ability to request credentials for other users. Then we have some generic security code that we can use to request a users credentials from inside the session beans, based on the users identity from their initial login (just as you are doing it via getCallerPrincipal()).
We also place the users identity in a thread local variable, so that classes down the call chain from the EJB do not have to be "container aware". They simply access the identity from the thread local and use the security classes to look up user profile information. This also makes it easy to change the implementation for testing, or even something other than LDAP lookups.
Other conveniences we created were a JDBCServiceLocator that retrieves connections with user/password for the current user. So the developer does not have to explicitly code the security lookups at all.
Normally the Java EE security model will not allow the retrieval of the user password, for security reasons. But it depends on the implementation. Some vendors provide methods to retrieve this kind of information, but if you rely on such implementations, be aware that the portability of the application will be compromised.
One common approach is to write a servlet filter to intercept the login request and save a copy of the credentials, to be used later. If your application doesn't use the Java EE security infrastructure, this could be easily implemented. That's because some vendors prevent you from filtering an authentication servlet.
Robin,
Sounds like what I was planning. I figured I'd make a call right after a successful server connection to load the credentials into a threadLocal variable on my connection class. I was hoping there was an easier way - but I guess not.