Spring - SaltSource is null - java

I'm using Spring Security and Spring Boot. I'm using too a UserDetails and UserDetailsService.
When execution passed into DaoAuthenticationProvider class and the method additionalAuthenticationChecks(...), the SaltSource is null.
Do you know why ? Perhaps a configuration is needed ?
Thx.

You have to set the salt source. See for example this question as a possible way to do that: https://stackoverflow.com/a/26149525/185031

A SaltSource is needed to be configured. You can use one of its available implementations: SystemWideSaltSource or ReflectionSaltSource.
If you choose ReflectionSaltSource, you have to specify which property of UserDetails will be used for the salt. You may use any existing property of your UserDetails implementation (i.e username) or a specific salt field.
From security perspective, you should better consider a securely generated random salt. In that case, BCryptPasswordEncoder does the job for you (generating salt + storing it with the password).
Here are samples configurations found here.
In XML:
<bean id="authProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="customUserService" />
<property name="passwordEncoder" ref="encoder" />
</bean>
<bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
In java:
auth.jdbcAuthentication().dataSource(dataSource)
.passwordEncoder(passwordEncoder())
.usersByUsernameQuery("sql...")
.authoritiesByUsernameQuery("sql...");

Related

How to perform user-locking in Spring-MVC?

I wanted to know how I can perform user locking (or the best way to perform the same) i.e. if a user is already logged in from a device and tries to login from another device, he/she should be notified that a session is already available for that user and an option to close other session and start a new one.
Framework Used Spring-MVC + hibernate 4.1.
And one more thing: how can I set a list of some user hashmap object in application context?
That can be done with Spring Security and Conncurrent Session Control. You can define how many sessions may exist concurrently and decide what to do if the maximum exceeds.
Their is a simple xml configuration in spring security for the same. First you have to register the SessionRegistry bean. I have used default class of SessionRegistryImpl of spring security for Session registry like :
<bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
After that we have to register the ConcurrentSessionControlStrategy with container and tell it the maximum session allowed per user.
Example:
<bean id="sessionStrategy"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<property name="maximumSessions"
value="${security.config.sessionStrategy.maximumSessions.value}" />
<property name="exceptionIfMaximumExceeded" value="true" />
</bean>
security.config.sessionStrategy.maximumSessions.value is the integer value specified in property file. By varying the maximumSessions property value we can define maximum concurrent users easily.

Spring Security Authoriaztion

There is one web application created using Spring 3.2 + Hibernate 4 + maven.
Now I want to do authenticate and authorization based on user role. As of now I am not concentrating on authentication. Lets say user is valid and I have a roles somewhere in the object.
Now I want to get started with the authorization part. I am new and not sure how to proceed. I did some R & D on net but it seems quite tough.
I have one document in which how I need to do is written.There are some question I would like to ask :
A Role Based Access Control framework is adopted to control permission : Please explain little bit. I think it is talking about authorization based on role.
UI Level Permissions, Method Level Permissions, Object Level Permissions : I search on net and found Object level permission is something like create ACL( access control list ) and it seems very complex. why it s required to have object level permission.
Dynamic permission evaluation on object : Why it is required.
I search on net found #PreAuthorize and #PostAuthorize is there on method level permission. Is Spring AOP is required to do this. As of now we are now using Spring AOP in application.
Please help me how to start.
for authorization you need to configure few things in security.xml file
first you need to load the roles on which you want to authorize
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="preauthAuthProvider"/>
</sec:authentication-manager>
<bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="userDetailsService"/>
</bean>
</property>
</bean>
You need create a bean name userDetailsService to fetch all the roles from DB or any other source.
Now you need to configure a decision manager by configuring a role voter saying that on which type of roles you want to authorize
<bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
after that you need to configure a filter security interceptor where you need to define a intercept url where you need to define a protected resource uri and access with the roles you want to protect
<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
<property name="securityMetadataSource">
<sec:filter-security-metadata-source lowercase-comparisons="true">
<sec:intercept-url pattern='/test**' access='testRole'/>

Spring security changing sessionid

I'm using spring security 3.1.4 and I have the following problem:
I implemented my custom SavedRequestAwareAuthenticationSuccessHandler and I implemented a cache SessionRegistry.
The problem is that the session id that I get in the SessionRegistry.registerNewSession is different then the on i get in SavedRequestAwareAuthenticationSuccessHandler .onAuthenticationSuccess
The session registery is called first.
what is the correct one? How can I get the same in both?
Is there a way that the custom SessionRegistry.registerNewSession will take the spring security session id?
Just a mere guess. But it sounds like the following issue.
In Spring security by default there is a feature enabled called session fixation protection.
It migrates the session to a new ID for a security reason.
Imagine somebody supplies you an url with an existing session ID via email, you click the link and login.
Now the person who can supplied you the url, can simply hack your account by using the supplied session id.
If you want to disable it, you can do so by putting the following line in your spring security configuration. However be aware of the risk.
<http .. >
...
<session-management session-fixation-protection="none">
...
</http>
The way I solved it was with the below steps:
Added a new bean for SessionFixationProtectionStrategy
<bean id="sessionFixationProtectionStrategy" class="org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy" />
Added the new bean in # 1 as a property to the AuthenticationFilter bean
<bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
...
<property name="sessionAuthenticationStrategy" ref="sessionFixationProtectionStrategy" />
...
</bean>
Added a session management configuration with session-fixation-protection property in the <security:http> tag
<security:http>
<security:headers />
<security:csrf disabled="true"/>
...
<security:session-management session-fixation-protection="changeSessionId" />
</security:http>
Per Spring Security doco, SessionFixationProtectionStrategy is used as SessionAuthenticationStrategy for Java EE Servlet API implementations pre 3.1 - https://docs.spring.io/spring-security/site/docs/4.2.13.BUILD-SNAPSHOT/apidocs/org/springframework/security/web/authentication/session/SessionFixationProtectionStrategy.html, whilst from Servlet API 3.1, ChangeSessionIdAuthenticationStrategy should be used.

Custom Permission Evaluator

I'm trying to override the default permission evaluator in Spring Security 3.0, but no matter what I do, the permission elevator is ignored and the default, DenyAllPermissionEvaluator is invoked instead.
I'm using programmatic configuration, and I've tried setting the permission evaluator by overriding the configure(WebSecurity) and configure(Http) methods of the WebSecurityConfigurerAdapter class, but this doesn't help much.
What is the proper way of setting a custom permission evaluator that will actually be used by Spring Security?
Using xml conf
<security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled">
<security:expression-handler ref="methodSecurityExpressionHandler"/>
</security:global-method-security>
<bean id="methodSecurityExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="permissionEvaluator" ref="defaultPermissionEvaluator"/>
</bean>
and then simply define your bean like normal :
<bean id="defaultPermissionEvaluator" class="com.your.class.implements.permissionevaluator"/>
haven't done with java conf (am I the only person still using xml conf?), but shouldn't be to hard to convert from the above. And make sure you are defining in the correct place, which in most situations is the root context, hwoever we did it in the web context, so as to secure the controllers

using form-login in a Multi-tenant webapp using Spring MVC and Spring Security

I created a small and simple webapp using Spring Security and SpringMVC and I'm trying to convert it to be a multi-tenant application.
The concept I want is to re-use actual JSPs I have and alter their contents based on configuration which I determine based on the path of the URL.
Example:
Customer #1 (abc) - URL: http://mydomain.com/abc/login.html
Customer #2 (xyz) - URL: http://mydomain.com/xyz/login.html
So the name of the "tenant" is a prefix to the page's path.
I modified my controller to be like this:
#Controller
#RequestMapping("/{customer:[a-zA-Z0-9]+}/login.htm")
public class LoginController
{
private static final Logger logger = Logger.getLogger(LoginController.class);
#RequestMapping
#ReadOnlyRequest
public String login(#PathVariable("customer") String customer, HttpServletRequest request)
{
// Do some 'customer' related actions here
return "login"; // Map to the 'login.jsp' view
}
}
My view resolver configuration is:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
Until now, I had the following form-login configuration:
<form-login
login-page="/login.htm"
authentication-failure-url="/login.htm?error=true"
login-processing-url="/login_process"
default-target-url="/index.jsp"
always-use-default-target="true"
/>
But I do not know how to convert it to support my changes.
Is there a way to convert it to something like:
<form-login
login-page="/${customer}/login.htm"
authentication-failure-url="/${customer}/login.htm?error=true"
login-processing-url="/${customer}/login_process"
default-target-url="/index.jsp"
always-use-default-target="true"
/>
One possible idea is to use URL rewriting instead of manual handling of tenant identifiers. This way you can completely decouple tenant handling logic from your code, for example, as follows:
You define an inbound rewriting rule that converts /abc/login.html to /login.html and saves tenant identifier as a request attribute.
You define an outbound rule that appends the current tenant identifier to URLs being written into response. I think Spring Security should respect such a rule when sending redirects (if it doesn't, you can define a custom RedirectStrategy).
Though I have not tested this idea and cannot be sure that it would work.
See also:
OCPSoft Rewrite
UrlRewriteFilter

Categories