Reputation: 65
Im currently migrating to spring sec 4 but got trouble. These are my setting down below.
My security.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- Exclude all files and folders under resources for security -->
<security:http pattern="/resources/**" security="none" />
<security:http auto-config="true" disable-url-rewriting="false">
<security:headers disabled="true"/>
<security:csrf disabled="true"/>
<security:intercept-url pattern="/login" access="permitAll"/>
<security:intercept-url pattern="/**" access="hasAnyRole('RS001', 'RS002', 'RS003')"/>
<security:form-login login-page="/login"/>
<security:logout logout-success-url="/login"/>
</security:http>
<bean id="userDetailService" class="vm.security.UserDetailServiceImpl" />
<!-- For hashing and salting the password -->
<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<security:authentication-manager>
<security:authentication-provider ref="authProvider"></security:authentication-provider>
</security:authentication-manager>
<bean id="authProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailService" />
<property name="passwordEncoder" ref="encoder" />
</bean>
<!-- To load the message properties for overwrite default spring security error message -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:message"/>
</bean>
</beans>
Custom UserDetailSevice
package vm.security;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import vm.data.dto.VmAccount;
import vm.data.dto.VmSystemResource;
import vm.exception.VmException;
import vm.service.AuditLogService;
import vm.service.UserAccountService;
import vm.util.PropertiesConstants;
public class UserDetailServiceImpl implements UserDetailsService {
private static final Logger logger= Logger.getLogger(UserDetailServiceImpl.class);
@Autowired
private AuditLogService auditLogService;
@Autowired
private PropertiesConstants propertiesConstants;
@Autowired
private UserAccountService userAccountService;
@Override
public UserDetails loadUserByUsername(String userid) throws UsernameNotFoundException{
try{
VmAccount account = userAccountService.getVmAccountById(userid);
if(account != null){
List<VmSystemResource> systemResourceList = userAccountService.getUserSystemResources(userid);
List<GrantedAuthority> roles= new ArrayList<GrantedAuthority>();
for(VmSystemResource resource : systemResourceList)
roles.add(new SimpleGrantedAuthority(resource.getResourceId()));
UserDetails user = new User(account.getUserid(), account.getPwd(), (account.getStatus().equals(propertiesConstants.getCoreStatusActive()) ? true : false), true, true, true, roles);
logger.info(roles);
auditLogService.addAuditDetails(userid, new Date(), propertiesConstants.getAuthentication(), propertiesConstants.getLoginSucceed());
return user;
}
throw new UsernameNotFoundException(userid + " not found.");
}catch (VmException ce){
logger.error(ce.getErrorCode(),ce);
throw new UsernameNotFoundException(ce.getErrorCode() + ":userid object is null");
}
}
}
Login.jsp
<!DOCTYPE html>
<html lang="en">
<head>
<link href="${pageContext.request.contextPath}/resources/css/bootstrap-3.3.4.min.css" rel="stylesheet">
<style type="text/css">
/* For nav header not to overlap*/
body {
padding-top:150px;
background-color: #eee;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-6 col-xs-offset-3">
<div class="panel panel-primary">
<div class="panel-body">
<form id="creForm" class="form-horizontal" method="post" action="${pageContext.request.contextPath}/login">
<div id="errPanel" class="form-group">
<div class="col-xs-8 col-xs-offset-3">
<span style="color: red;">${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}</span>
</div>
</div>
<div class="form-group">
<label class="col-xs-4 control-label" for="userid">USERID:</label>
<div class="col-xs-6">
<input name="username" type="text" class="form-control" placeholder="USERID" />
</div>
</div>
<div class="form-group">
<label class="col-xs-4 control-label" for="name">PASSWORD:</label>
<div class="col-xs-6">
<input name="password" type="password" class="form-control" placeholder="PASSWORD" />
</div>
</div>
<div class="form-group">
<div class="col-xs-6 col-xs-offset-4">
<button type="submit" class="btn btn-primary">SIGN IN</button>
</div>
</div>
</form>
</div>
<div class="panel-footer">
</div>
</div>
</div>
</div>
</div>
</body>
</html>
My problem is when i replace with old version spring security 3.2.7 it is working fine. But spring security 4 always lead me to access denied page. Hope somebody will help me.
Upvotes: 2
Views: 1405
Reputation: 124888
There have been several changes in Spring Security 4 changes to the defaults and also changes to make behavior more consistent. You are running into a change made for consistency (SEC-2578) meaning all hasRole
(and it derivates) are now prefixing the incoming parameter with the role prefix which is by default ROLE_
and this wasn't the case before Spring 3.2 (but was so in other places).
To fix you have 3 options
ROLE_
when converting them. hasAnyAuthority
instead of hasAnyRole
Upvotes: 2