How to override InvalidSessionStrategy in Spring Security - spring

The default implementation of InvalidSessionStrategy i.e. SimpleRedirectInvalidSessionStrategy in Spring security redirects the request to a default url. This default url comes from a final variable.
I would like to override the behavior by not redirecting all the time to the same url. How could I achieve that ? If I create a custom implementation of InvalidSessionStrategy, how can I use that ?
This is my configuration right now
and()
.addFilterAfter(mySpringSecurityConfig.forceLogoutFilter(), PreAuthenticationFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.invalidSessionUrl("http://xxx/login.jsp")
.sessionAuthenticationErrorUrl(PropertyMgr.getCarnivalURL("http://xxx/login.jsp"))
But I don't want to use "http://xxx/login.jsp" for all invalid sessions. Thanks for the help.

Please post your entire configuration and the Spring Security version, so that we can have the whole picture.
However, to override InvalidSessionStrategy, simply define your class implementing this interface.
Then find a way to put your implementation into SessionManagementFilter.
One way can be via SessionManagementConfigurer.
In the worst case you can always extend SessionManagementFilter, put your InvalidSessionStrategy there, and substitute the default sesssion filter.

Related

Securing and permitting access to spring rest controller with ant matcher and method level security side-by-side?

First of all my application is build with spring boot and security.
So I have several rest controllers (resources). One controller provides multiple methods to get/post different kind of data. But I have cases where some methods should be public and others needs authentication.
For example:
GET /api/object/method1 <-- Needs authentication
GET /api/object/method2 <-- Public
POST /api/object/method3 <-- Needs authentication
POST /api/object/method4 <-- Public
What is best practice to secure this resource? I can't secure url with antMatcher with following pattern /api/object/**. Because then the public methods would be secured as well. Also I can't secure by request type (GET, POST).
One option I thought about was using only method level security (eg #Secured etc). This would mean that I need to annotate a lot of methods.
Another thought that comes to mind is dividing resource to 2 parts.
For example creating
ObjectResource.java
ObjectResourcePublic.java
One controller base URL would be /api/public/ and second simply /api/
Then I could use antMatcher for these URLS.
Is my only option to secure every path separtely or every method separetly?
What other options do I have to do this kind of partial securing one resource?
You may use below methods apart from above mentioned methods.
1. Write Interceptor/filter
2. Use Aspect and define advise

How do I setup login service for Spring-social and spring-security over a REST API?

I want to have a JS application in on client-side (no jsps) that will communicate with back-end only with REST calls. I want also to enable users to be able to login with FB, Twitter accounts. In addition, I also want to enable users to register their own accounts. For this purpose I want to use Spring-security and spring-social on backend and Javascript SDK in front to get access_token from the FB, which will be then passed to backend.
The question is: how do I create a REST controller that would authenticate using spring-social and spring-security facilities?
I read through the examples in:
https://github.com/spring-projects/spring-social-samples
but couldn't really find how I could make use of ProviderSignInController or SpringSocialConfigurer for this purpose. I guess I cannot use the SocialAuthenticationFilter in my case since the "/auth/{providerid}" url is not what I'm looking for. However, I guess the ProviderSingInController seems to be of use here neither. Please correct me if I'm wrong. Ideally I would like to benefit from all capabilities of Spring Security framework.
I will appreciate any suggestions.
Best regards
EDIT
I would like to follow a flow like here: http://porterhead.blogspot.com/2013/01/writing-rest-services-in-java-part-4.html but using the Spring Social and Spring Security combined.
The front-end application is written in AngularJS
2nd EDIT
It turns out that you can simply make use of all the Spring Social modules benefits out of the box. The only thing a client has to do is call a GET on the auth/facebook or whatever link to fire entire 0auth dance which will eventually return the authentication result. Then you can control the flow easily (register account or return some relevant information to the client to let know registration is needed). So the SpringSocialConfigurer works well in this case (apart from the fact that it doesn't support scope setting yet, however, this can be changed manually, check my pull request # github.com/spring-projects/spring-social/pull/141)
3rd EDIT - 14.10.2014
As requested, I will share how I managed to make it work.
Given I have configured my security filter in the following way:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
public void configure(final HttpSecurity http) throws Exception {
http.formLogin()
...
.and().apply(getSpringSocialConfigurer());
}
private SpringSocialConfigurer getSpringSocialConfigurer() {
final SpringSocialConfigurer config = new SpringSocialConfigurer();
config.alwaysUsePostLoginUrl(true);
config.postLoginUrl("http://somehost.com:1000/myApp");
return config;
}
Once my application is set up, the only thing I need to call is http://somehost.com:1000/myApp/auth/facebook
with GET request.
"In addition, I also want to enable users to register their own
accounts"
If you say that you want to allow users to login with their own credentials (without FB/twiter), you need to let them also to create account, and to support forgot password, etc...
If that is the case, maybe this SO thread might be helpful. The auth-flows package also supports REST API.
Create Account, Forgot Password and Change Password

Storing Form Login Sessions in a Database

A security context on my Spring server uses Spring Security's built-in form login implementation. Currently, login sessions are being stored locally, in memory, by the servlet container. I'd like to replace the way HttpSessions are stored and retrieved with one of my Spring Data Mongo repositories. I looked for one of those "slots" in the Java configuration for session management, but didn't find anything. To be clear, I'm looking for the equivalent of a UserDetailsService, but for sessions.
Here's the relevant snippet of Java configuration in my security configuration class:
...
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.formlogin()
.loginProcessingUrl("/authentication/login")
.successHandler(successHandler)
.usernameParameter("username")
.passwordParameter("password")
.failureUrl("/login?error")
.loginPage("/login")
.and()
.logout()
.logoutUrl("/authentication/logout")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.logoutSuccessUrl("/login")
.and()
...
As far as I can tell, I'm not doing anything particularly strange. It may not be relevant, but I wanted to show precisely what I'm looking at when I say I couldn't find the correct configuration slot.
I looked closely at the source code for the SecurityContextPersistenceFilter, which seems to be the filter in Spring Security's filter chain responsible for retrieving and storing HttpSessions. It delegates session retrieval to a call to getSession() in HttpServletRequest, and session storage to saveContext() in an injected SecurityContextRepository.
In order to correctly replace the default, server-local session storage mechanism, I see three approaches.
Plug in a Spring Data-backed security context repository into the persistence filter. Then, wrap incoming requests to implement custom getSession() behavior that queries the custom security context repository rather than local storage. The built-in persistence filter will then "do the right thing".
Set up an ObjectPostProcessor to replace the default filter with a custom SecurityContextPersistenceFilter that uses my Spring Data repository directly rather than calling getSession() or a using security context repository. I've actually never used an object post processor before, so if that's not what they're meant for, please tell me.
The last option is not one I'm considering, but it's worth mentioning. I think that underneath all the magic, Spring Security really delegates to the servlet container's implementation of session storage. So one way to change the backing store to Mongo would be to use something like Tomcat's Manager interface to customize the session persistence behavior. This is not something I want to do because it becomes quite separate from Spring, I lose the ability to use my services via dependency injection, and it depends completely on the container, making it difficult to change at whim.
I'm sure that gutting out the session storage and replacing it with a database is a fairly common requirement for Spring servers. How is it usually done? If I'm just missing a configuration option, I'd love to see where it's located. Otherwise, suggestions about which route to take (and why) are what I'm looking for.
In Spring 3 the place is in SessionManagement.
Basically you define the session filter and specialise either the session strategy or the session registry.
The session registry is in charge of dealing with session invalidation and creation. In that point you could persist whatever is that you need to persist.
The downside of this approach is that it requires either that you declare the session event publisher in web.xml file or that you handle everything.
An example would be to implement SessionRegistry and SessionAuthenticationStrategy. From there when a user authenticates or a getSession(true) (or invalidate it) is executed it will reach the code and there you can act upon it. Your strategy would have your session registry injected. If a user authenticates through the authentication chain it would reach your strategy, which would pass the session to your registry.
An alternative approach is to add a custom filter of your own. A class extending GenericFilterBean. And then register it:
<security:custom-filter ref="customSessionFilter" after="LAST" />
In this example it would be executed last. This is useful since you could check for an active session or a successfully authenticated user.
An approach similar to your option #3 without relying on container-specific interfaces would be to use Spring Session with a MongoDB-backed SessionRepository implementation.
This would handle persisting all HTTP Session data rather than only the bits specific to Spring-security.

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/

Can I use expressions in Apache Shiro security annotations?

I've been doing some comparisons between Apache Shiro and Spring Security - I'm really loving the security model that Shiro uses and believe it to be far cleaner that Spring Security.
However, one big nice-to-have would be to be able to reference method parameters from within the method-level security annotations. For example, right now I could so something like:
#RequiresPermissions("account:send:*")
public void sendEmail( EmailAccount account, String to, String subject, String message) { ... }
Within the context of this example, this means that the authenticated user must have the permission to send emails on email accounts.
However, this is not fine-grained enough, as I want instance level permissions! In this context, assume that users can have permissions on instances of email accounts. So, I'd like to write the previous code something like this:
#RequiresPermissions("account:send:${account.id}")
public void sendEmail( EmailAccount account, String to, String subject, String message) { ... }
In this way, the permission string is referencing a parameter passed into the method such that the method can be secured against a particular instance of EmailAccount.
I know I could easily do this from plain Java code within the method, but it would be great to achieve the same thing using annotations - I know Spring Security supports Spring EL expressions in its annotations.
Is this definitely not a feature of Shiro and thus will I have to write my own custom annotations?
Thanks,
Andrew
Look at the classes in http://shiro.apache.org/static/current/apidocs/org/apache/shiro/authz/aop/package-summary.html, especially PermissionAnnotationHandler. There you can see that all Shiro does when encountering the #RequiresPermissions annotation is call getSubject().isPermitted(permission) and does no substitution inside the annotation value at all. You would have to somehow override that handler if you wanted this kind of functionality.
So to answer your question: yes, this is definitely not a feature of Shiro and you have to either write your own annotation or somehow override that handler.
This feature is currently not supported by Shiro. Multiple people have requested this feature. Perhaps we can vote for the issue?
https://issues.apache.org/jira/browse/SHIRO-484
https://issues.apache.org/jira/browse/SHIRO-77
https://issues.apache.org/jira/browse/SHIRO-417
https://issues.apache.org/jira/browse/SHIRO-331

Resources