【问题标题】:determine target url based on roles for struts2根据 struts2 的角色确定目标 url
【发布时间】:2012-03-24 19:43:36
【问题描述】:

我是 struts 和 spring security 的新手。 谁能帮我弄清楚如何将不同角色的不同用户重定向到不同的网址?换句话说,struts2中如何使用action controller根据用户角色提供确定目标url?

我找到了以下问题determine target url based on roles in spring security 3.1,但我不知道如何配置操作。

我尝试了以下设置,但它不起作用:

security.xml

 <form-login login-page="/login" authentication-failure-url="/login?error=true" login-processing-url="/j_security_check" default-target-url="/default"/>

struts.xml

<action name="default" class="com.moblab.webapp.action.RoleRedirectAction" method="defaultAfterLogin"/>

RoleRedirectAction.java

package com.moblab.webapp.action;
import javax.servlet.http.HttpServletRequest;
public class RoleRedirectAction extends BaseAction{

public String defaultAfterLogin(HttpServletRequest request) {
    if (request.isUserInRole("ROLE_ADMIN")) {
        return "redirect:/<url>";
    }
    return "redirect:/<url>";
}
}

非常感谢。

编辑 1 我还尝试了以下注释

 @Action(value="/default",results={@Result(name="success",location="/querySessions")})

编辑 2 我的最终解决方案如下所示。我不确定这是否是最好的方法,但它确实有效:

public class StartPageRouter extends SimpleUrlAuthenticationSuccessHandler {


@Autowired
private UserService userService;

protected final Logger logger = Logger.getLogger(this.getClass());
private RequestCache requestCache = new HttpSessionRequestCache();

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


    Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

    //default path for ROLE_USER
    String redirectPath = <url>;

    if (authorities != null && !authorities.isEmpty()) {

        Set<String> roles = getUserRoles(authorities);

        if (roles.contains("ROLE_ADMIN"))
            redirectPath = <url>;
        else if (roles.contains("ROLE_INSTRUCTOR"))
            redirectPath = <url>;
    }

    getRedirectStrategy().sendRedirect(request, response, redirectPath);
}

public void setRequestCache(RequestCache requestCache) {
    this.requestCache = requestCache;
}

private Set<String> getUserRoles(Collection<? extends GrantedAuthority> authorities) {

    Set<String> userRoles = new HashSet<String>();

    for (GrantedAuthority authority : authorities) {
        userRoles.add(authority.getAuthority());
    }
    return userRoles;
}
}

编辑 3 这里有更好的解决方案:

http://oajamfibia.wordpress.com/2011/07/07/role-based-login-redirect/#comment-12

【问题讨论】:

    标签: authentication struts2 spring-security authorization j-security-check


    【解决方案1】:

    假设您的意思是您希望根据用户分配的角色将用户重定向到不同的起始页面,那么您可以试试这个。请注意,我在 Struts 之外执行所有这些操作。

    首先创建您自己的扩展 Springs SimpleUrlAuthenticationSuccessHandler 的类并覆盖 onAuthenticationSuccess() 方法。实际的重定向是在 onAuthenticationSuccess() 方法中通过 getRedirectStrategy().sendRedirect(request,response,); 行执行的。

    因此,您所需要的只是一种替换您自己的网址的方法。

    所以,例如我有

    package com.blackbox.x.web.security;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.log4j.Logger;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
    import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
    import org.springframework.security.web.savedrequest.RequestCache;
    
    import com.blackbox.x.entities.UserDTO;
    import com.blackbox.x.services.UserService;
    
    
    public class StartPageRouter extends SimpleUrlAuthenticationSuccessHandler {
    
    
     @Autowired
     UserService userService;
    
     @Autowired
     LoginRouter router;
    
    
     protected final Logger logger = Logger.getLogger(this.getClass());
     private RequestCache requestCache = new HttpSessionRequestCache();
    
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication) throws IOException,
            ServletException {
    
    
        requestCache.removeRequest(request, response);
    
        User user = (User) authentication.getPrincipal();
        UserDTO userDTO = userService.find(user.getUsername());
    
        getRedirectStrategy().sendRedirect(request, response, router.route(userDTO));
    }
    
    public void  setRequestCache(RequestCache requestCache) {
                this.requestCache = requestCache;
            }
    }
    

    其中 LoginRouter 是我自己的类,它接受登录的用户,并根据分配的角色确定用户应该被引导到哪个 URL。

    然后您配置 Spring Security 以使用您的版本使用

    authentication-success-handler-ref="customTargetUrlResolver"/> 
    

    <beans:bean id="customTargetUrlResolver" class="com.blackbox.x.web.security.StartPageRouter"/>
    

    在您的安全上下文 xml 文件中。

    【讨论】:

    • 谢谢。您的回复很有帮助。不过我有几个问题。 1、为什么需要requestCache.removeRequest(request, response); 2. 为什么 request 没有角色,为什么我不能使用 request.isUserInRole() ?谢谢。
    • 1) 我不确定,但我认为这是因为 Spring 在路由到登录过程之前缓存了原始浏览器请求,登录过程用于在成功登录后重定向用户。因此,如果用户请求安全资源,Spring 会缓存请求,执行身份验证,然后将用户重定向到他们最初请求的页面。由于我们在登录后强制用户访问特定页面,因此我们不需要最初请求的页面 - 所以我们只是在整理。
    • 2) 我不知道,request.isUserInRole() 应该可以工作。当然,将 ActionSupport 扩展为您的操作的基类并使用 isUserInRole() 对我有用。
    猜你喜欢
    • 1970-01-01
    • 2018-05-27
    • 2011-06-05
    • 2017-11-29
    • 2011-12-29
    • 2014-11-14
    • 2015-09-09
    • 2013-10-25
    • 1970-01-01
    相关资源
    最近更新 更多