【问题标题】:spring security redirect based on role基于角色的spring安全重定向
【发布时间】:2014-03-26 00:47:34
【问题描述】:

我有以下 spring-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.0.xsd">

    <http auto-config="true">
           <intercept-url pattern="/Freelancer/**" access="ROLE_FREELANCE" />
           <intercept-url pattern="/Client/**" access="ROLE_CLIENT" />
           <intercept-url pattern="/Agency/**" access="ROLE_AGENCY" />
           <intercept-url pattern="/Manager/**" access="ROLE_MANAGER" />
           <intercept-url pattern="/User/**" access="ROLE_USER" />
           <form-login default-target-url="/${role}" login-page="/login.jsp" />
           <logout logout-url="/logout" logout-success-url="/" />
    </http>

    <authentication-manager>
           <authentication-provider>
             <jdbc-user-service data-source-ref="dataSource" 
               users-by-username-query="select user_name,password, enabled from Users where user_name=?"  
               authorities-by-username-query="select u.user_name, u.role from Users u where u.user_name =?"/>                 
           </authentication-provider>
    </authentication-manager>

</beans:beans>  

我想要什么,我想将用户重定向到他们的工作区,例如,如果客户端登录,那么他将被重定向到 /Client/index.jsp,如果代理登录,他们将被重定向到 /Agency/index .jsp.

之前有没有办法访问角色,他会被重定向到他们在spring-security.xml文件中的工作空间。

<form-login default-target-url="/${role}" login-page="/login.jsp" />

我的目录结构类似于角色。

有什么想法。

【问题讨论】:

    标签: spring spring-security


    【解决方案1】:

    编写一个 spring 控制器,它将根据用户角色为不同的页面提供服务。编写身份验证成功处理程序类并编写代码以根据角色决定重定向的位置。

    首先需要更改&lt;form-login /&gt;标签。

    <form-login login-page="/landing" authentication-success-handler-ref="authSuccessHandler" />
    
    <beans:bean id="authSuccessHandler" class="com.package.AuthSuccessHandler" />
    

    删除default-target-url 属性。让身份验证处理程序决定将用户重定向到哪里。

    Auth 成功处理程序类将如下所示:

    public class AuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
        @Override
        protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
            // Get the role of logged in user
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            String role = auth.getAuthorities().toString();
    
            String targetUrl = "";
            if(role.contains("client")) {
                targetUrl = "/client/index";
            } else if(role.contains("agency")) {
                targetUrl = "/agency/index";
            }
            return targetUrl;
        }
    }
    

    这是一个示例代码。根据您的要求更改它。

    【讨论】:

    • 那是在 CustomService.java 上,我们将角色映射到 spring secuiry ? ?
    【解决方案2】:

    您可以通过使用这样的自定义成功处理程序来使用基于注释的解决方案:

    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.web.DefaultRedirectStrategy;
    import org.springframework.security.web.RedirectStrategy;
    import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
    import org.springframework.stereotype.Component;
    
    @Component
    public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    
        private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
    
        @Override
        protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
                throws IOException {
            String targetUrl = determineTargetUrl(authentication);
    
            if (response.isCommitted()) {
                System.out.println("Can't redirect");
                return;
            }
    
            redirectStrategy.sendRedirect(request, response, targetUrl);
        }
    
        /*
         * This method extracts the roles of currently logged-in user and returns
         * appropriate URL according to his/her role.
         */
        protected String determineTargetUrl(Authentication authentication) {
            String url = "";
    
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
    
            List<String> roles = new ArrayList<String>();
    
            for (GrantedAuthority a : authorities) {
                roles.add(a.getAuthority());
            }
    
            if (isDba(roles)) {
                url = "/db";
            } else if (isAdmin(roles)) {
                url = "/admin";
            } else if (isUser(roles)) {
                url = "/home";
            } else {
                url = "/accessDenied";
            }
    
            return url;
        }
    
        private boolean isUser(List<String> roles) {
            if (roles.contains("ROLE_USER")) {
                return true;
            }
            return false;
        }
    
        private boolean isAdmin(List<String> roles) {
            if (roles.contains("ROLE_ADMIN")) {
                return true;
            }
            return false;
        }
    
        private boolean isDba(List<String> roles) {
            if (roles.contains("ROLE_DBA")) {
                return true;
            }
            return false;
        }
    
        public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
            this.redirectStrategy = redirectStrategy;
        }
    
        protected RedirectStrategy getRedirectStrategy() {
            return redirectStrategy;
        }
    
    }
    

    安全配置为:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    
    @Configuration
    @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Autowired
        CustomSuccessHandler customSuccessHandler;
    
        @Autowired
        public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("USER");
            auth.inMemoryAuthentication().withUser("admin").password("root123").roles("ADMIN");
            auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
          http.authorizeRequests()
            .antMatchers("/", "/home").access("hasRole('USER')")
            .antMatchers("/admin/**").access("hasRole('ADMIN')")
            .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
            .and().formLogin().loginPage("/login").successHandler(customSuccessHandler)
            .usernameParameter("ssoId").passwordParameter("password")
            .and().csrf()
            .and().exceptionHandling().accessDeniedPage("/Access_Denied");
        }
    
    }
    

    【讨论】:

    • 在 .loginPage("/login") 之后的安全配置文件中,您必须将日志记录处理 Url 添加为 .loginProcessingUrl("here yout url")
    【解决方案3】:

    最好检查授予权限的角色是否相等,如果同一部分存在多个角色,则包含可能会失败。

    在表单登录配置中添加身份验证成功处理程序,如下所示:

    <http auto-config="true">
        <intercept-url pattern="/Freelancer/**" access="ROLE_FREELANCE" />
        <intercept-url pattern="/Client/**" access="ROLE_CLIENT" />
        <intercept-url pattern="/Agency/**" access="ROLE_AGENCY" />
        <intercept-url pattern="/Manager/**" access="ROLE_MANAGER" />
        <intercept-url pattern="/User/**" access="ROLE_USER" />
        <form-login login-page='/login.html'
                    authentication-failure-url="/login.html?error=true"
                    authentication-success-handler-ref="myAuthenticationSuccessHandler"/>
        <logout logout-url="/logout" logout-success-url="/" />
    </http>
    

    成功处理程序是这样的:

    public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    
        protected Log logger = LogFactory.getLog(this.getClass());
    
        private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
    
        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
            handle(request, response, authentication);
            clearAuthenticationAttributes(request);
        }
    
        protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
            String targetUrl = determineTargetUrl(authentication);
    
            if (response.isCommitted()) {
                logger.debug(
                        "Response has already been committed. Unable to redirect to "
                                + targetUrl);
                return;
            }
    
            redirectStrategy.sendRedirect(request, response, targetUrl);
        }
    
        protected String determineTargetUrl(Authentication authentication) {
            boolean isUser = false;
            boolean isFreelance = false;
            boolean isClient = false;
            boolean isAgency = false;
            boolean isManager = false;
            Collection<? extends GrantedAuthority> authorities
                    = authentication.getAuthorities();
            for (GrantedAuthority grantedAuthority : authorities) {
                if (grantedAuthority.getAuthority().equals("ROLE_FREELANCE")) {
                    isFreelance = true;
                    break;
                } else if (grantedAuthority.getAuthority().equals("ROLE_CLIENT")) {
                    isClient = true;
                    break;
                } else if (grantedAuthority.getAuthority().equals("ROLE_AGENCY")) {
                    isAgency = true;
                    break;
                } else if (grantedAuthority.getAuthority().equals("ROLE_MANAGER")) {
                    isManager = true;
                    break;
                } else if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
                    isUser = true;
                    break;
                }
            }
    
            if (isFreelance) {
                return "freelance/homepage.html";
            } else if (isClient) {
                return "client/homepage.html";
            } else if (isAgency) {
                return "agency/homepage.html";
            } else if (isManager) {
                return "manager/homepage.html";
            } else if (isUser) {
                return "user/homepage.html";
            } else {
                throw new IllegalStateException();
            }
        }
    
        protected void clearAuthenticationAttributes(HttpServletRequest request) {
            HttpSession session = request.getSession(false);
            if (session == null) {
                return;
            }
            session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
        }
    
        public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
            this.redirectStrategy = redirectStrategy;
        }
    
        protected RedirectStrategy getRedirectStrategy() {
            return redirectStrategy;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-04-04
      • 2016-06-04
      • 2014-07-20
      • 1970-01-01
      • 2018-01-24
      • 2013-03-21
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多