迁移到Spring Security 4获得了Access deinied页面

时间:2015-07-22 03:02:04

标签: java spring spring-mvc spring-security

我目前正在迁移到第4阶段,但遇到了麻烦。 这些是我在下面的设置。

我的security.xml文件

    <?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>

自定义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>

我的问题是当我用旧版本弹簧安全3.2.7替换它工作正常。 但春季安全4总是引导我访问被拒绝的页面。 希望有人能帮助我。

1 个答案:

答案 0 :(得分:2)

Spring Security 4对默认值进行了一些更改,并且还进行了一些更改以使行为更加一致。您正在进行针对一致性的更改(SEC-2578),这意味着所有hasRole(并且它派生)现在为传入参数添加前缀,该角色前缀默认为ROLE_,这不是& #3;春天3.2之前的情况(但在其他地方也是如此)。

要修复你有3个选项

  1. 按照迁移指南中的here
  2. 进行操作
  3. 在转换时,只需在ROLE_前添加角色前缀。
  4. 使用hasAnyAuthority代替hasAnyRole