Spring security custom fields - model-view-controller

1) How can i add a custom field in my login form and use that value to navigate to a different page after login. I need a custom authentication provider for authenticating. Can we use spring mvc to tie all this?
2) How can we get hold of HttpSession in auth provider?

1) I guess, you can choose the default behavior by implementing your own AuthenticationSuccessHandler and passing it to <form-login authentication-success-handler-ref="..."/>
2) This is actually not in the vein of the separation of concerns paradigm in Spring Security where the authentication provider populates the Authentication object and another filter persists/populate the authentication in/from the HTTP session. Nevertheless, you can in general have access to the current HTTP request and, therefore a session, from anywhere inside the request processing chain by adding the filter org.springframework.web.context.request.RequestContextListener to your web.xml. Use then ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession() to reach the session from your authentication provider.

Related

How does spring security maintain authentication information between request?

How does spring security maintain authentication info between requests?
Does it use any thing similar to jSessionId or uses an entirely different mechanism.
Further, I see that the AbstractSecurityInterceptor (I mean, any of it's implementations) is responsible for intercepting the incoming request and verify if a request is already authorized using Authentication.isAuthenticated() and then depending on the condition either validate the request or send the Authentication request to an AuthenticationManager Implementation. So, in other words, how does AbstractSecurityInterceptor differentiate between first request and subsequent request.
Spring Security uses a SecurityContextRepository to store and retrieve the SecurityContext for the current security session.
The default implementation is the HttpSessionSecurityContextRepository which utilizes the javax.servlet.http.HttpSession to store/retrieve the SecurityContext.
The underlying servlet container will obtain the correct HttpSession for the incoming request, generally due to a session identifier being passed in a cookie or request parameter. For Spring Security it doesn't matter as that is thus loaded of to the underlying servlet container.

Spring JDBC Authentication vs LoadUserByName Differences

Im new on spring security and I had some research on authentication ,I saw two options there are some guys posted.First one Jdbc authentication or In memory authentication ,and there are also loadUserByName(UserDetailService).
what is difference between them ,and also what is use case of loadUserByName (UserDetailService)
This is the official reference https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jc-authentication
For In Memory Authentication, you have a set of username-password pair hard-coded in your xml/java config class.
In jdbc authentication, you can have a direct database contact to fetch users and authorities, provided you have configured a datasource
You can define custom authentication by exposing a custom UserDetailsService as a bean. You can do whatever functionality to return an instance of UserDetails in loadUserByUsername(). This method is called implicitly to authenticate a user, when creating an authentication.

For validating session attribute, which is better in spring - Interceptor or Spring AOP?

In my application, after a user is logged in, every time he sends a request (get/post), before calling the method in controller, i want to verify the session attribute set in the request (i set a session attribute during his login). I see that this can be implemented through spring interceptors (OR) spring AOP. which one should i use?. I have a feeling interceptors are outdated. Or is there a way in spring security which does this for me?
So you want this intercept to happen only for all the controller methods ..? Does the controller have Base URL that its getting invoked for (post/get/delete)...? Is it more like you want to intercept the http request for a particualt URL ..? like this one
<intercept-url pattern="/styles/**" filters=" .." />
If your use case is boiled down to a particular URL pattern then you can write a custom filter extending GenericFilterBean and you can plug it to the filters attribute.So this will get called for every request matching url pattern and in your custom filter you can do whatever you wanted to do.
What if you try implementing a simple Filter? You can extend already existing Spring filter, or create your own by implementing javax.servlet.Filter
The spring security way seems the best way to me with access to specific roles also can be assigned. very good example given in http://www.mkyong.com/spring-security/spring-security-form-login-using-database/

Spring Security, Customizing Authorization, AccessDecisionManager vs Security Filter

I'm going to implement a custom authorization based on ([User<-->Role<-->Right]) model and Rights should be compared to controller and method name (e.g. "controller|method").
I used customizing UserDetails and AuthenticationProvider to adjust granted authority (here), but as checked source codes and docs about how customizing the compare of authority I found there is a filter SecurityContextHolderAwareRequestWrapper) that implements isGranted and isUserInRole to compare authority, while the documents say using AccessDecisionManager voters to customize (As I understood). Which one should be used ? Where I have controller and method(action) name to compare authority with them ?
I got confused about Spring security a little. Is there any other resource than official docs that illustrate how it works, I mean sequence of actions and methods and how customize them.
There are several approaches:
Role based, where you assign each user a role and check the role before proceeding
Using Spring security expressions
There is also a new spring acl components which lets you perform acl control on class level and are stored in a database.
My personal usage so far has been 1 and 2, where you only assign roles to users.
But option 3 allows you to create finer grained security model, without having to rebuild your webapp when chaning the security model
Role Based
A role based security mechanism can be realised implementing the UserDetailsService interface and configuring spring security to use this class.
To learn on how to such a project can be realized, take a look at the following tutorials:
Form based login with in memory user database Link
Form based login with custom userdetails service Link
In short spring security performs the following behind the scenes:
Upon authentication (e.g. submitting a login form) an Authentication Object is created which holds the login credentials. For example the UsernamePasswordAuthenticationFilter creates an UsernamePasswordAuthenticationToken
The authentication object is passed to an AuthenticationManager, which can be thought of as the controller in the authentication process. The default implementation is the ProviderManager
The AuthenticationManager performs authentication via an AuthenticationProvider. The default implementation used is the DaoAuthenticationProvider.
The DaoAuthenticationProvider performs authentication by retrieving the UserDetails from a UserDetailsService. The UserDetails can be thought of as a data Object which contains the user credentials, but also the Authorities/Roles of the user! The DaoAuthenticationProvider retrieves the credentials via its loadUserByUsername method
and then compare it to the supplied UsernamePasswordAuthenticationToken.
UserDetailsService collects the user credentials, the authorities and builds an UserDetails object out of it. For example you can retrieve a password hash and authorities out of a database. When configuring the website url-patterns you can refer to the authorities in the access attribute. Furthermore, you can retrieve the Authentication object in your controller classes via the SecurityContextHolder.getContext().getAuthentication().
Furthemore to get a better understanding of the inner workings of these classes you can read the javadocs:
UserDetails - how the user credentials are stored and accessed
AuthenticationManager.authenticate(..) - contract on how AuthenticationExceptions are handled
UserDetailsService.loadUserByUsername(..)- contact on how username lookup failures are handled, e.g. user does not exist
Spel
Instead of checking authorities, SPEL enables you also to check other properties of a user.
You can use these in the URL patterns, but also annotate methods with #Preauthorize.
This way securing the business layer is less intrusive.
ACL Based
The ACL based model was introduced in spring security 3.0, but hasn't been well documented.
Their suggestion is to look at the Contacts XML example, since this one uses their new acl component.
Last this book contains great examples on how to further customize your security wishes.

How to handle requests if no matching spring security <intercept-url>?

I'm using spring 3.1.1 and spring security 3.1.0. I'd like to enforce a policy that all http requests that are not explicitly configured with an <intercept-url pattern="..." access="..."/> entry are handled in a particular way. For requests that match a configured <intercept-url/> I want to use typical role based access decisions. However, for non-matching requests, I want to either respond with a 404 (not found) (or maybe 403/forbidden). I want to do this so that I and other team members are forced to explicitly configure spring security and associated roles for any new endpoints.
I originally thought that I could use <intercept-url pattern="/**" access="denyAll"/> as the last intercept-url and that spring would do what I wanted. This technique works if the user is already authenticated but is a little strange for unauthenticated/anonymous users. For anonymous users, spring detects (in ExceptionTranslationFilter) that the user is anonymous and starts the authentication process when requests like /missingResource are processed. Typically this means that the user is redirected to a login form and, after logging in, is redirected back to /missingResource. So the user has to login in order to see a 404 (not found) page.
I ended up removing the intercept-url pattern="/**" access="denyAll"/> and writing a custom filter that runs after="FILTER_SECURITY_INTERCEPTOR" and responds with 404 for requests that are not matched by the FilterSecurityInterceptor but it seemed a little complicated. Is there a better or simpler way?
you can define a separate http element for intercept url /** with access ="denyAll" and add a custom entry-point-ref to avoid spring to redirect user to login form, you can use existing entryPoint Http403ForbiddenEntryPoint for showing 403 error response or implement your own by implementing AuthenticationEntryPoint.
Hope it helps.

Resources