使用spring security进行身份验证后如何根据角色进行重定向[重复]

Posted

技术标签:

【中文标题】使用spring security进行身份验证后如何根据角色进行重定向[重复]【英文标题】:How can redirect based on role after authentication with spring security [duplicate] 【发布时间】:2014-07-03 20:52:45 【问题描述】:

我使用 spring security、spring、hibernate 和 jsf 身份验证正常工作,但它总是将我重定向到页面 home.jsf

我想在认证后管理用户的访问权限

我想在认证后管理用户的访问权限

如果权限 = ROLE_ADMIN 重定向 ves homeadmin.jsf

if authority = ROLE_RH redirect ves homerh.jsf

如果权限 = ROLE_EXCUTIVE 重定向 ves homeex.jsf

如果权限 = ROLE_MANAGER 重定向 ves homem.jsf

if authority = ROLE_GP redirect ves homegp.jsf

Collaborateur 表中的权限字段

Colaborateur 类是

private Integer idColaborateur;
    private Rolecol rolecol;
    private String matriculeColaborateur;
    private String nomColaborateur;
    private String prenomColaborateur;
    private String mailColaborateur;
    private String pwdColaboratuer;
    private String loginColaborateur;

    private String adresseColaborateur;
    private Boolean flgSuspendu;
    private Set<HistoriqueNoteObjctif> historiqueNoteObjctifs = new HashSet<HistoriqueNoteObjctif>(
            0);
    private Set<Note> notes = new HashSet<Note>(0);
    private Set<NoteObjectifs> noteObjectifses = new HashSet<NoteObjectifs>(0);
    private Set<CompagneDevaluation> compagneDevaluations = new HashSet<CompagneDevaluation>(
            0);
    private Set<ColaborateurHierarchique> colaborateurHierarchiques = new HashSet<ColaborateurHierarchique>(
            0);
    private String authority;
  //getter and seter

数据源配置在文件applicationContext.xml中

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="root" />
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/modulevsql" />
        <property name="password" value="root" />
        <property name="maxStatementsPerConnection" value="0" />
        <property name="maxAdministrativeTaskTime" value="0" />
        <property name="maxConnectionAge" value="0" />
        <property name="maxIdleTime" value="0" />
        <property name="maxIdleTimeExcessConnections" value="0" />
        <property name="maxPoolSize" value="0" />
        <property name="maxStatements" value="0" />
    </bean>

用户类是

public class User implements UserDetails 


    private static final long serialVersionUID = 1L;
    private String name;
    private String password;
    private Colaborateur user;

    public void setUser(Colaborateur user) 
        this.user = user;
    

    public User(String name) 
        FacesContext fc=FacesContext.getCurrentInstance();      
        UserBean userBean=(UserBean) fc.getApplication().createValueBinding("#UserBean").getValue(fc);

        userBean.chargerUtilisateur(name);
        user = userBean.getUtilisateur();


        System.err.println("USERS    >>> "+user);


        PasswordSupport pswdSupport = new PasswordSupport();

        if (user!=null)

            System.out.println("User.getLogin() :"+user.getLoginColaborateur());
            System.out.println("user.getPwd() :"+user.getPwdColaboratuer());
            this.name=user.getMatriculeColaborateur();
            this.password=user.getPwdColaboratuer();
            System.err.println(pswdSupport.getMD5Hash("1"));
        
    


    public Collection<GrantedAuthority> getAuthorities() 

        List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();



        System.out.println("GrantedAuthorityImpl  1");
        System.out.println("GrantedAuthorityImpl  2");
        System.out.println("GrantedAuthorityImpl  3");
        System.out.println("GrantedAuthorityImpl  4");

        grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_VISITEUR"));


        return grantedAuthorities;
    
           //getter and setter

这是 applicationContext-security.xml 文件

<?xml version="1.0" encoding="UTF-8"?>

<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.1.xsd">

      <global-method-security secured-annotations="enabled">
      </global-method-security>


      <http pattern="/modules/members/**" access-denied-page="/modules/members/accessDenied.jsf" authentication-manager-ref="MembersAuthenticationManager">

              <intercept-url pattern="/modules/members/secure/**" access="ROLE_VISITEUR" /> 
            <intercept-url pattern="/modules/members/secure/homeadmin.jsf" access="ROLE_ADMIN" />

            <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />

            <form-login login-page="/modules/members/login.jsf"
                   default-target-url="/modules/members/secure/home.jsf" 
                  login-processing-url="/modules/members/j_spring_security_check"
                  authentication-failure-url="/modules/members/login.jsf" /> 
            <logout logout-url="/modules/members/secure/logout"
                  logout-success-url="/modules/members/login.jsf" delete-cookies="true" />

      </http>


      <authentication-manager alias="MembersAuthenticationManager">
            <authentication-provider user-service-ref="securityManager">
                  <password-encoder hash="md5" />
            </authentication-provider>
      </authentication-manager>
      <beans:bean id="securityManager" class="tn.com.security.SecurityManager" />

</beans:beans>

这是 MyAuthSuccessHandler 类

@Component
public class MyAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler 

    //    @Autowired
    //    private UserService userService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException 

        //        // changeLastLoginTime(username)
        // userService.changeLastLoginTime(authentication.getName());

        setDefaultTargetUrl("/modules/members/secure/home.jsf");

        super.onAuthenticationSuccess(request, response, authentication);
    


    protected boolean hasRole(String role) 
        // get security context from thread local
        SecurityContext context = SecurityContextHolder.getContext();
        if (context == null)
            return false;

        Authentication authentication = context.getAuthentication();
        if (authentication == null)
            return false;

        for (GrantedAuthority auth : authentication.getAuthorities()) 
            if (role.equals(auth.getAuthority()))
                return true;
        

        return false;
    

如何更新 MyAuthSuccessHandler 类、USer 和 applicationContext.xml 文件 认证后管理用户的访问权限

如果权限 = ROLE_ADMIN 重定向 ves homeadmin.jsf

if authority = ROLE_RH redirect ves homerh.jsf

如果权限 = ROLE_EXCUTIVE 重定向 ves homeex.jsf

如果权限 = ROLE_MANAGER 重定向 ves homem.jsf

如果权限 = ROLE_GP 重定向 ves homegp.jsf

这是 UserBean 类

@Component("UserBean")
@Scope("session")
public final class UserBean implements Serializable 

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Autowired
    private Colaborateurservice colaborateurservice;

    private Colaborateur utilisateur;

    public UserBean() 
        super();
        // TODO Auto-generated constructor stub
    

    @PostConstruct
    public void initiate() 

        try 

         catch (Exception e) 
            e.printStackTrace();

        

    

    public void testBean() 
        System.out.println("testBean");

    

    public void chargerParametreGlob() 

        try 

            System.out.println("chargerParametreGlob  ");

         catch (Exception e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        

    

    public void chargerUtilisateur(String login) 
        System.out.println(login);
        try 

            utilisateur = new Colaborateur();
            List<Colaborateur> list = colaborateurservice
                    .findByMatriculeColaborateurlo(login);

            System.out.println(list);

            if (list.size() > 0) 

                this.utilisateur = (Colaborateur) list.get(0);
                System.out.println("utilisateur.getLogin() :"
                        + utilisateur.getMatriculeColaborateur());

                System.out.println("utilisateur.getPwd() :"
                        + utilisateur.getLoginColaborateur().length());
            

         catch (Exception e) 
            e.printStackTrace();

        

    

    public String logout() 
        FacesContext context = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) context.getExternalContext()
                .getSession(true);
        if (session == null) 
            return "logout";
         else 
            session.invalidate();
            return "logout";
        
    

    public void setUtilisateur(Colaborateur utilisateur) 
        this.utilisateur = utilisateur;
    

    public Colaborateur getUtilisateur() 
        return utilisateur;
    


【问题讨论】:

【参考方案1】:

您正在扩展AuthenticationSuccessHandler,调用super.onAuthenticationSuccess() 并不能真正帮助您。

尝试以下方法:

public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler 

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authResult)
        Collection<? extends GrantedAuthority> auths = authResult.getAuthorities();
        for (GrantedAuthority authorities : auths)
        
            if (authorities.getAuthority().equals("ROLE_ADMIN"))
                response.sendRedirect(response.encodeURL("homeadmin.jsf");
            
            else if(authorities.getAuthority().equals("ROLE_RH"))
                response.sendRedirect(response.encodeURL("homerh.jsf");
        .  .  .
           //Repeat pattern until all roles checked
        

然后将您的配置更改为:

<http pattern="/modules/members/**" 
    <!-- Pass in a reference to your customAuthenticationSuccessHandler -->
    authentication-success-handler-ref="customAuthenticationSuccessHandler"
    access-denied-page="/modules/members/accessDenied.jsf" 
    authentication-manager-ref="MembersAuthenticationManager">

        <intercept-url pattern="/modules/members/secure/**" access="ROLE_VISITEUR" /> 
        <intercept-url pattern="/modules/members/secure/homeadmin.jsf" access="ROLE_ADMIN" />

        <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />

        <form-login login-page="/modules/members/login.jsf"
              default-target-url="/modules/members/secure/home.jsf" 
              login-processing-url="/modules/members/j_spring_security_check"
              authentication-failure-url="/modules/members/login.jsf" /> 
        <logout logout-url="/modules/members/secure/logout"
              logout-success-url="/modules/members/login.jsf" delete-cookies="true" />

  </http>

<beans:bean id="customAuthenticationSuccessHandler"  
      class="foo.bar.CustomAuthenticationSuccessHandler" />

扩展SimpleUrlAuthenticationSuccessHandler 几乎没有意义,因为您无法设置希望超类将您发送到的位置。您也可以实现AuthenticationSuccessHandler 接口并将您的自定义实现传递给Spring Security。

还因为您正在实现一个接口,您可以自动装配任何服务类。

假设每个用户只有一个角色,我自己也使用过这种方法,并且效果很好。如果用户拥有多个角色,他们将被重定向到找到的第一个角色。您可能希望对 if 语句进行排序,以便将用户发送到责任最小的区域。

【讨论】:

感谢您在尝试实现代码时提供的帮助,但是有一个例外类型 Collection 不是通用的;它不能用参数参数化 extends GrantedAuthority>我不知道它是什么,因为这是我第一次使用 Spring Security

以上是关于使用spring security进行身份验证后如何根据角色进行重定向[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Boot/Spring Security 对 LDAP 进行证书身份验证

使用 Spring 和 Spring Security 进行 REST 身份验证

使用 Spring Security 3 进行 LDAP 身份验证

使用 Spring Security + Spring 数据 + MongoDB 进行身份验证

如何使用spring security使用空密码进行基本身份验证?

使用 Spring Security 在 Spring 中进行 WebSocket 身份验证