We are using Spring 3 framework and we have a SSO (Single sign on) provider which redirects to our app passing special tokens in the request to indicate the user is authenticated.
I would like to use Spring security to handle stuff like denying access to pages unless the user is authenticated, but I'd also like to be able to bypass this on my local machine while developing the application.
So in the production scenario, I expect the SSO to redirect to our app, specifically to a "/login.html" target which is supposed to somehow trigger a custom class I write to pull the expected login info from request and load up the user's info from our database and put it in session for the rest of the app to use.
Then in the development scenario I need to bypass SSO by just being able to create a session using a custom login page and then load the user's info from database just as above.
I am trying to figure out how to do it myself but I can't seem to wrap my head around all of it.
Any info on how to accomplish this even just high level kind of road map would be a huge help
If you write a custom AuthenticationProvider for Spring Security to authenticate with your SSO provider, then you could have two Spring Security configurations, one that wires up your custom AuthenticationProvider for production and one for development that uses a standard authentication provider.
Related
We have an existing legacy web application(Servlet+jsp+spring+hibernate) and we are going to develop some new features of the application using a new stack (angularjs+Spring mvc). Currently suggested approach is to register a new servlet and develop the new features in the same codebase, so the authenticated users will have access to the new functionality we develop in the system. Is there a better way of doing this as a two different web applications (without SSO) ? Can two web applications be secured under the same form based authentication settings ?
I think architecture and security usability is very important before dive into something.
If both apps use same login, then I assume the newer application is more likely a service oriented application. Ex: RESTful
Authorization may be an issue. Ex: Legacy app is used by user set A, new one is used by both user set A and B.
Otherwise you can use a shared database for example MongoDB to store your login info i.e token.
When you log in, return that token and use for the other service via angular client. When you log out remove any token for that user session. You may also need to concern about token expiration.
However you have to refactor your legacy system in someway to use a token. If it is not possible, you can use session sharing which is handled by the the container if the the both apps are running under same container. Ex: Tomcat. But now it may very hard to integrate with a native mobile app if you are hoping to do so.
Sharing session data between contexts in Tomcat
From the point of Spring security and angularjs, authenticating via form is just an http POST with content type being application/x-www-form-urlencoded. One difference is the response to a non authenticated request, for one response should be a http redirect (jsp, to a login page), one with an unauthorized code (for angularjs). That could be handled with a custom AuthenticationFailureHandler or on the client side. A similar difference may occur for the successful login redirection.
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 have an application deployed to Google App Engine. Within the application, there are 2 roles: standard user, and administrator. I have form based authentication setup, and the URL's that require authentication (for example /admin and /account) are setup to require any role (*), just so I can be sure that Google has authenticated them. I have a filter setup for the admin path as well as the account path that talks to backend business logic to see if the user has an account within my application before forwarding them to the page they requested, or redirecting if necessary.
This seems cumbersome, in that for each request, the filter uses the UserService to get the google user in order to determine whether or not the person authenticated by google has an account within the application. I know that within the context of an application deployed to a traditional application server, I could actually define the application level role required to access a url, and since the application server would know about the roles/users for the application, that would be sufficient, but since google is handling the authentication, would I be correct in assuming that I have to handle the access requirements on a per request basis, as I am now with the use of filters? I chose to use filters to try to keep the actual servlet 'cleaner', so that I know that when a client request reaches the servlet, they have been authenticated and are authorized to access those resources.
Would it be wise to carry that data around (whether a user is authenticated and whether or not they are an admin or standard user) in a session? That's the only other alternative I can come up with. I'm not sure how expensive it is to access the UserService for every single request, because that is in turn accessing the datastore. I would imagine there has to be a better way to handle authentication.
Not really sure if it's an optimal solution but what we do now is store a User session (our own implementation, not GAEs) and we cache it aggressively using Objecitfy's cache feature. That way we only hit the datastore on login/logout and most queries after that are virtually free (because of the use standard session time on our app, cache flush is not really a concern)
We are using Spring Security and it is working fine in the single web application. Now, I need to create another Web application with Spring security. In the first application the user can sell his/her stuff (e.g. EBay). The second app which I am creating now, it is for general users where he can save his general preferences, searches, save some items he looked at etc. He may/may not be the existing user. So the difference between the two users are:
User 1 (existing user): Can post his stuff for sale.
User 2: He/she should be able to login. Save his general activities etc. & if he/she wants to sell his/her item, he/she needs to go thru the additional steps for verification.
All this cannot be done in just one application due to some reasons. My question is on how to handle the security? Should I create separate security filters for each applications or is there a way to use common security implementation who can manager both of these application. Please provide your feedback, I would really appreciate it.
if you wrap both components in two different webapps, each will have his own spring security web filter infrastructure.
So in principle there will be a security session for each web application, to be backed by whatever authentication system you use.
If you use JDBC then the user would have to login twice.
If you want your customers to only login once, you can for example use a token based system.
When you cross link from webapp 1 to webapp 2, you could hook the links up to a redirect servlet.
The servlet then generates a token, persists it in a database and forwards the user with the token in the url to the other webapp.
In spring security you can then implement your own PRE_AUTH_FILTER which reads out the token, verifies if it is persisted in the Database.
For security reasons you should make these tokens only one use.
I have a couple of Java-based web applications developed. Both the applications have separate Authentication logic based on some ActiveX directory implementation.
Now, I need to change this to Windows authentication so that whenever the user hits the URLs of my web applications, instead of redirecting him to login page I need to check his Windows credentials.
I do not want to store his windows credentials in URL.
Is there any good way to do this ?
Depending on the level of integration you want your web application to have, Spring Security should have you covered in just about all aspects of what you are after.
If redirecting to a login page and authenticating the entered credentials against an Active Directory server via LDAP is acceptable, then the LDAP extension is the way to go.
If you want more of a Single Sign On (SSO) flow and your users are already authenticated against the authoritative Active Directory server in question (eg. they are logged in to the domain), then the Kerberos plugin for Spring Security may be more appealing, since your users will simply have to go to the web application and won't have to go through any other authentication steps. The systems will take care of it behind the scenes.
You can also combine / layer these approaches if you which and try Kerberos-based authentication first and if that falls through, fall back to a login form and LDAP-based authentication.
If you need to go beyond that, Spring Security is flexible enough to allow you to use OpenID or in-app authentication as well if needed.
I'd recommending using Active Directory to expose it's windows authentication layer over LDAP, which can then be hit by something like Spring Security.
This would effectively force anyone using your application to use their windows login.