代码之家  ›  专栏  ›  技术社区  ›  sefirosu

Spring security jdbc配置以验证具有多个角色的用户

  •  1
  • sefirosu  · 技术社区  · 8 年前

    我目前正在开发一个基于java的发票应用程序。 我需要的是,要验证具有多个角色的用户,例如Peter应该具有角色role_SETTING、role_REPORT、role_QUOTE,而Anne只有一个角色role_SETTING等。。。

    这是我的spring-security-config.xml

    <beans:beans xmlns="http://www.springframework.org/schema/security"  
     xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
     xsi:schemaLocation="http://www.springframework.org/schema/beans  
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
     http://www.springframework.org/schema/security  
     http://www.springframework.org/schema/security/spring-security-3.2.xsd">  
    
     <http auto-config="true">  
      <access-denied-handler error-page="/403page" />  
      <intercept-url pattern="/makebill*" access="ROLE_ADMIN,ROLE_MAKEBILL" />
      <intercept-url pattern="/report*" access="ROLE_ADMIN,ROLE_REPORT" />
      <intercept-url pattern="/stock*" access="ROLE_ADMIN,ROLE_STOCK" />
      <intercept-url pattern="/customer*" access="ROLE_ADMIN,ROLE_CUSTOMER" />
      <!-- <intercept-url pattern="/setting*" access="ROLE_ADMIN,ROLE_SETTING" />   -->
      <intercept-url pattern="/mainmenu*" access="ROLE_ADMIN,ROLE_MAKEBILL,ROLE_SETTING,ROLE_CUSTOMER,ROLE_REPORT,ROLE_STOCK" />  
      <form-login 
        login-page='/login' username-parameter="username"  
       password-parameter="password" default-target-url="/mainmenu"  
       authentication-failure-url="/login?authfailed" />  
      <logout logout-success-url="/login?logout" />  
     </http>  
    
     <authentication-manager> 
         <authentication-provider>  
            <jdbc-user-service 
                data-source-ref="dataSource"  
                users-by-username-query="select username,password, enabled from person where username=?"  
                authorities-by-username-query="select username, role from person, role where username =?  " />  
         </authentication-provider> 
     </authentication-manager> 
    
    
    </beans:beans>  
    

    身份验证管理器目前只使用一个角色,我的意思是…当sql查询 authorities-by-username-query="select username, role from person, role where username =? " 运行,如果返回的值只是一个角色,例如 ROLE_REPORT ,应用程序工作正常,但如果有类似db的记录, ROLE_REPORT,ROLE_SETTING,ROLE_CUSTOMER ,当查询检索到该值时,应用程序将返回404错误,似乎我无法授予用户多个角色。

    谁能告诉我我做错了什么吗。 谢谢

    1 回复  |  直到 8 年前
        1
  •  1
  •   sefirosu    8 年前

    我自己找到了一个解决方案,实现了我自己的UserDetails,下面是代码

    @Service("assembler")
    public class Assembler {
    
      @Transactional(readOnly = true)
      User buildUserFromUserEntity(Person person) {
    
        String username = person.getUsername();
        String password = person.getPassword();
        boolean enabled = true;
    
        List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
        String[] authStrings = person.getRole().split(",");
        for(String authString : authStrings) {
            System.out.println("all auth roles: " + authString);
            authorities.add(new SimpleGrantedAuthority(authString));
        }
    
    
        User user = new User(username, password, enabled,
          true, true, true, authorities);
    
        return user;
      }
    }
    
    
    
    
    
    
    @Service("userDetailsService") 
    public class UserDetailsServiceImpl implements UserDetailsService {
    
      @Autowired private PersonService personService;
      @Autowired private Assembler assembler;
    
      @Transactional(readOnly = true)
      public UserDetails loadUserByUsername(String username)
          throws UsernameNotFoundException, DataAccessException {
    
        UserDetails userDetails = null;
        Person person = null;
    
        List<Person> listPeople = personService.listPeople();
        for (Person p: listPeople) {
            if (p.getUsername().equals(username)) {
                person = p;
            }
        }
    
        if (person == null)
          throw new UsernameNotFoundException("user not found");
    
        return assembler.buildUserFromUserEntity(person);
      }
    }
    

    这是spring-security-config.xml

    <http auto-config="true">  
      <access-denied-handler error-page="/403page" />  
      <intercept-url pattern="/makebill*" access="ROLE_ADMIN,ROLE_MAKEBILL" />
      <intercept-url pattern="/report*" access="ROLE_ADMIN,ROLE_REPORT" />
      <intercept-url pattern="/stock*" access="ROLE_ADMIN,ROLE_STOCK" />
      <intercept-url pattern="/customer*" access="ROLE_ADMIN,ROLE_CUSTOMER" />
      <intercept-url pattern="/setting*" access="ROLE_ADMIN,ROLE_SETTING" />
      <intercept-url pattern="/mainmenu*" access="ROLE_ADMIN,ROLE_MAKEBILL,ROLE_SETTING,ROLE_CUSTOMER,ROLE_REPORT,ROLE_STOCK" />  
      <form-login 
        login-page='/login' username-parameter="username"  
       password-parameter="password" default-target-url="/mainmenu"  
       authentication-failure-url="/login?authfailed" />  
      <logout logout-success-url="/login?logout" />  
     </http>  
    
    
     <beans:bean id="daoAuthenticationProvider"
     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
      <beans:property name="userDetailsService" ref="userDetailsService"/>
    </beans:bean>
    
    <beans:bean id="authenticationManager"
        class="org.springframework.security.authentication.ProviderManager">
      <beans:property name="providers">
        <beans:list>
          <beans:ref local="daoAuthenticationProvider" />
        </beans:list>
      </beans:property>
    </beans:bean>
    
    <authentication-manager>
      <authentication-provider user-service-ref="userDetailsService">
    
      </authentication-provider>
    </authentication-manager>
    

    我现在能够完美地为单个用户分配多个角色。 感谢阅读:)