根据spring security 3.1中的角色确定目标URL

时间:2011-11-30 13:19:04

标签: spring spring-security spring-3

在spring security 3.0中,我们正在使用AuthenticationProcessingFilter类,我们使用determineTargetUrl()方法,该方法根据不同的角色返回url。

现在,我们正在转向Spring security 3.1.0.RC3,我现在应该如何确定基于不同角色的URL,因为AuthenticationProcessingFilter类已从新版本中删除。任何人都可以请给我一些简短的代码,以便我可以实现自定义过滤器以重定向到不同角色的不同页面。

2 个答案:

答案 0 :(得分:21)

根据角色确定目标网址的最佳方法是在Spring Security配置中指定目标网址,如下所示。这将适用于Spring 3.0或3.1

<http>
    ... 
    <form-login login-page="/login" default-target-url="/default"/>
</http>

然后创建一个处理default-target-url的控制器。控制器应根据滚动重定向或转发。下面是使用Spring MVC的示例,但任何类型的控制器都可以工作(即Struts,Servlet等)。

@Controller
public class DefaultController {
    @RequestMapping("/default")
    public String defaultAfterLogin(HttpServletRequest request) {
        if (request.isUserInRole("ROLE_ADMIN")) {
            return "redirect:/users/sessions";
        }
        return "redirect:/messages/inbox";
    }
}

这种方法的优点是它没有与任何特定的Security实现相结合,它没有耦合到任何特定的MVC实现,并且它可以轻松地与Spring Security命名空间配置一起工作。在我今年在SpringOne上展示的SecureMail项目中可以找到一个完整的例子。

另一种方法是您可以创建自定义AuthenticationSuccessHandler。实现可能会扩展SavedRequestAwareAuthenticationSuccessHandler,它是默认的AuthenticationSuccessHandler。然后可以使用命名空间进行连接,如下所示。

<sec:http>
    <sec:form-login authentication-success-handler-ref="authSuccessHandler"/>
</sec:http>
<bean:bean class="example.MyCustomAuthenticationSuccessHandler"/>

我不建议这样做,因为它与Spring Security API相关联,最好在可能的情况下避免这种情况。

答案 1 :(得分:0)

在成功认证后,使用自定义认证成功处理程序根据用户角色指定重定向。

您需要创建以下自定义身份验证成功处理程序:

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.AuthenticationSuccessHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

public class CustomeAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response, Authentication authentication) throws IOException {
        handle(request, response, authentication);
    }

    protected void handle(HttpServletRequest request,
                          HttpServletResponse response, Authentication authentication)
            throws IOException {
        String targetUrl = determineTargetUrl(authentication);
        if (response.isCommitted()) {
            return;
        }
        redirectStrategy.sendRedirect(request, response, targetUrl);
    }

    protected String determineTargetUrl(Authentication authentication) {
        boolean isTeacher = false;
        boolean isAdmin = false;
        Collection<? extends GrantedAuthority> authorities
                = authentication.getAuthorities();

        for (GrantedAuthority grantedAuthority : authorities) {
            if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
                isTeacher = true;
                break;
            } else if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {
                isAdmin = true;
                break;
            }
        }

        if (isTeacher) {
            return "/user/account";
        } else if (isAdmin) {
            return "/admin/account";
        } else {
            throw new IllegalStateException();
        }
    }
    public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
        this.redirectStrategy = redirectStrategy;
    }

    protected RedirectStrategy getRedirectStrategy() {
        return redirectStrategy;
    }
}

然后修改spring security xml文件并定义您的bean并使用它

   <bean id="customeAuthenticationSuccessHandler"
          class="com.test.CustomeAuthenticationSuccessHandler"/>
    <security:http auto-config="true" use-expressions="false">
        <security:form-login login-page="/sign-in" login-processing-url="/sign-in" username-parameter="username"
                             password-parameter="password"
                             authentication-success-handler-ref="customeAuthenticationSuccessHandler"
                             always-use-default-target="true"
                             authentication-failure-url="/sign-in?error=true"/>

        <security:logout logout-url="/logout" logout-success-url="/"/>
     ..
     ..
    </security:http>