有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么isAuthenticated()可以工作,而access=“hasRole('VERIFIED')”不能在Spring安全项目中工作?

我正在使用SpringSecurity和SpringMVC4.0.1开发Spring项目。代码(intercept url/loginsucess)对于access=“isAuthenticated()”可以正常工作,但是对于access=“hasRole('VERIFIED')”不起作用

春季安全。xml

<security:http auto-config='true' use-expressions='true'>
     <security:form-login login-page="/login" default-target-url="/loginSuccess" 
        authentication-failure-url="/checkVerification" 
        username-parameter="mobile_Number"
        password-parameter="password"
        always-use-default-target="true"/> 
      <security:intercept-url pattern="/loginCheck" access="hasRole('VERIFIED')"/>
      <security:intercept-url pattern="/loginSuccess" access="isAuthenticated()"/>
      <security:intercept-url pattern="/home" access="permitAll" />
      <security:intercept-url pattern="/RankOption/**" access="hasRole('VERIFIED')"/>
      <security:logout logout-url="/logout"/>

</security:http>

       <security:authentication-manager erase-credentials="false" alias="authenticationManager">
            <security:authentication-provider ref="myAuthenticationProvider">
            </security:authentication-provider> 
       </security:authentication-manager> 

    <b:bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

    <b:bean id="myAuthenticationProvider" class="com.cT.www.provider.CustomAuthenticationProvider">
    </b:bean>   

一些控制器。爪哇

@Component
   public class CustomAuthenticationProvider implements    AuthenticationProvider {

    public CustomAuthenticationProvider() {
        super();
    }


    @Autowired
    private PersonService personService;    


    @Override
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {

        System.out.println(authentication.getName() + "principal" +(String) authentication.getCredentials()+
                authentication.getAuthorities().size() + " " + authentication.getPrincipal().toString());
        BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();

        String username = authentication.getName();

        String password = authentication.getCredentials().toString();

        UserSignUp user = (UserSignUp) personService.loadUserByUsername(username);

        if (user == null || !user.getUsername().equalsIgnoreCase(username)) {
            throw new BadCredentialsException("Username not found.");
        }

        if(password != null || !password.isEmpty()){
            if (BCrypt.checkpw(bcryptPasswordEncoder.encode(password), user.getPassword())) {
                throw new BadCredentialsException("Wrong password.");
            }
       }

        List<Role> authorities = user.getAuthorities();

        return new UsernamePasswordAuthenticationToken(user, password, authorities);

    }

    @Override
    public boolean supports(Class<?> arg0) {
        // TODO Auto-generated method stub
        return true;
    }

}

ServiceImpl。爪哇

   @Override
    @Transactional
    public UserSignUp loadUserByUsername(String mobile_Number)
        throws UsernameNotFoundException {
    this.getMobile_Number_N_Password(Long.parseLong(mobile_Number));
    logger.trace("Trying to find User with mobile Number" + mobile_Number);



    List result = personDAO.getMobile_Number_N_Password(mobile_Number);

    String existing_Password = null;
    Boolean verification_Boolean = false;

    if(result != null){
        if(result.get(0) != null){
            for(Iterator itr = result.iterator(); itr.hasNext();){

                Object[] myResult = (Object[]) itr.next();

                existing_Password = (String) myResult[0];

                verification_Boolean = (Boolean) myResult[1];



            }           
        }   


    }   

    if(result == null){
        throw new UsernameNotFoundException("No user found with mobile number" + mobile_Number);
    }





    UserSignUp retrievedUserDetails = new UserSignUp();

    retrievedUserDetails.setMobile_Number(mobile_Number);
    retrievedUserDetails.setPassword(existing_Password);

    Role r = new Role();
    r.setName("VERIFIED");
    List<Role> roles = new ArrayList<Role>();
    roles.add(r);

    retrievedUserDetails.setAuthorities(roles);

    return retrievedUserDetails;


}

模型 角色爪哇

import org.springframework.security.core.GrantedAuthority;

public class Role implements GrantedAuthority {

    private String name;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    @Override
    public String getAuthority() {
        // TODO Auto-generated method stub
        return null;
    }

}

用户注册。爪哇

    @Column
    @ElementCollection
    private List<Role> authorities;

    public List<Role> getAuthorities() {
           return authorities;
    }

    public void setAuthorities(List<Role> authorities) {
          this.authorities = authorities;
    }

我还没有在db中设置列权限。这是否会引发问题。但是当我调试代码时,我看到authorities变量正在填充


共 (1) 个答案

  1. # 1 楼答案

    您使用“UserSignUp”引用作为 “新用户名PasswordAuthenticationToken(用户、密码、权限);”但它应该是对“委托人”的引用。许多身份验证提供程序将创建一个UserDetails对象作为主体。参考API

    如果你使用“组织”。springframework。安全果心用户详细信息。UserDetails’而不是UserSignUp,它应该可以工作

    下面是使用spring的“UserDetails”类的示例代码

    • 修改ServiceImpl。类loadUserByUsername(…)方法签名返回 'org。springframework。安全果心用户详细信息。用户详细信息“
    • 在UserDetails类中设置“已验证”权限角色

     List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        SimpleGrantedAuthority authority = new SimpleGrantedAuthority("VERIFIED");
        authorities.add(authority);
        UserDetails user = new User(mobile_Number, existing_Password, authorities);
    
            return user;
    
            .......
    
    • 您的SomeController中的更改。爪哇

    UserDetails user=(UserSignUp)personService。loadUserByUsername(用户名)

     return new UsernamePasswordAuthenticationToken(user, yourpassword, authorities);