具有Spring安全性的JSF-登录后重定向到指定页面 [英] JSF with Spring security - Redirect to specified page after login

查看:105
本文介绍了具有Spring安全性的JSF-登录后重定向到指定页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用JSF的Web应用程序,并且Spring安全性用于登录和授权.

I have a web application which uses JSF and Spring security is used for login and authorization.

当用户键入特定页面且未登录时,例如localhost:8080/APP/page.xhtml,应用程序将重定向到确定的登录页面.此后,用户已登录,但是他重定向到的页面是index.xhtml这是默认的欢迎页面,而不是page.xhtml.

When a user types in a specific page and he is not logged in, e.g. localhost:8080/APP/page.xhtml, the application redirects to the login page which is OK. After that, the user is logged in but the page he is redirected to is index.xhtml which is the default welcome page, and not to page.xhtml.

我想要以下行为:用户转到localhost:8080/APP/page.xhtml,他被重定向为登录后,应将他重定向到所需的页面-page.xhtml.

I want the following behaviour: user goes to localhost:8080/APP/page.xhtml, he is redirected to be logged in and after that he should be redirected to his desired page - page.xhtml.

已编辑- spring-security.xml 的代码段:

 <security:http auto-config="true">
    <security:intercept-url pattern="/javax.faces.resource/*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <security:intercept-url pattern="/login.xhtml" access="IS_AUTHENTICATED_ANONYMOUSLY"/>

    <security:intercept-url pattern="/**" access="ROLE_UNALLOCATED, ROLE_MANAGER"/>
    <security:intercept-url pattern="/pages/management/" access="ROLE_MANAGER"/>
    <security:intercept-url pattern="/pages/requests/" access="ROLE_UNALLOCATED, ROLE_EMPLOYEE, ROLE_TEAM_LEADER, ROLE_MANAGER"/>

    <security:form-login login-page="/login.xhtml" 
                          />
    <security:logout logout-url="/j_spring_security_logout"
            logout-success-url="/login.xhtml"
            invalidate-session="true"/>
</security:http>

有什么想法吗?谢谢

我认为是因为:

 <!-- Welcome page -->
<welcome-file-list>
    <welcome-file>/index.xhtml</welcome-file>
</welcome-file-list>

来自web.xml.我删除了它,但结果相同.

from web.xml. I removed this but with the same result.

以后的修改:

我刚刚在我的自定义loginController中注意到了if (authenticationResponseToken.isAuthenticated())之后的一行,这几乎肯定是问题的根源:

I just noticed a line in my custom loginController after if (authenticationResponseToken.isAuthenticated()) which is almost surely the source of the problem:

loginController:

The loginController:

@ManagedBean(name = "loginController")
@SessionScoped
@Controller
public class LoginController implements Serializable {
private static final long serialVersionUID = 1L;

@Autowired
IUserService userService;

@Autowired
@Qualifier("authenticationManager")
protected AuthenticationManager authenticationManager;

// save the current user after login to be able to inject it in other places
// as needed
private User currentUser;

/**
 * This action logs the user in and returns to the secure area.
 * 
 * @return String path to secure area
 */
public String loginUsingSpringAuthenticationManager() {
    // get backing bean for simple redirect form
    LoginFormBackingBean loginFormBean = (LoginFormBackingBean) FacesUtils
            .getBackingBean("loginFormBean");

    // simple token holder
    Authentication authenticationRequestToken = createAuthenticationToken(loginFormBean);

    // authentication action
    try {
        Authentication authenticationResponseToken = authenticationManager
                .authenticate(authenticationRequestToken);

        Authentication authCopy = null;
        final Object principal = authenticationResponseToken.getPrincipal();
        if (principal instanceof LdapUserDetailsImpl) {
            LdapUserDetailsImpl userImpl = (LdapUserDetailsImpl) principal;
            userImpl.getUsername();

            // here check if we already have a User with his DN in the DB
            // get the User by DN
            User u = userService.getUserByDn(userImpl.getDn());

            // if a user with this DN does not exist in the DB, create a new
            // one with the DN from LDAP and the default settings for a new
            // user
            if (null == u) {
                u = userService.createNewUserFromDn(userImpl.getDn(),
                        userImpl.getUsername());
            }
            // set the obtained user as the current user
            setCurrentUser(u);
            List<GrantedAuthority> grAuth = new ArrayList<GrantedAuthority>();
            // after this, do the role authority stuff
            // here loop through user roles if he has more and
            if (null != u.getUserTeamRoles()) {
                for (UserTeamRole urt : u.getUserTeamRoles()) {
                    // here get role for every UserTeamRole
                    grAuth.add(new SimpleGrantedAuthority(urt.getRole()
                            .getName()));
                }
            }

            // add the above found roles to the granted authorities of the
            // current authentication
            authCopy = new UsernamePasswordAuthenticationToken(
                    authenticationResponseToken.getPrincipal(),
                    authenticationResponseToken.getCredentials(), grAuth);
        }

        SecurityContextHolder.getContext().setAuthentication(authCopy);
        // ok, test if authenticated, if yes reroute
        if (authenticationResponseToken.isAuthenticated()) {
            // lookup authentication success url, or find redirect parameter
            // from login bean
            return "index.xhtml?faces-redirect=true";
        }
    } catch (BadCredentialsException badCredentialsException) {
        // FacesMessage facesMessage = new FacesMessage(
        // "Login Failed: please check your username/password and try again.");
        // FacesContext.getCurrentInstance().addMessage(null, facesMessage);
        FacesContext.getCurrentInstance().addMessage(
                null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        "Sample error message",
                        "Login Failed! Please check your credentials"));
    } catch (LockedException lockedException) {
        FacesMessage facesMessage = new FacesMessage(
                "Account Locked: please contact your administrator.");
        FacesContext.getCurrentInstance().addMessage(null, facesMessage);
    } catch (DisabledException disabledException) {
        FacesMessage facesMessage = new FacesMessage(
                "Account Disabled: please contact your administrator.");
        FacesContext.getCurrentInstance().addMessage(null, facesMessage);
    }

    return null;
}

private Authentication createAuthenticationToken(
        LoginFormBackingBean loginFormBean) {
    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
            loginFormBean.getUserName(), loginFormBean.getPassword());
    return usernamePasswordAuthenticationToken;
}

如何重定向到我需要的页面?我有一个包含用户和密码的loginBean,可以添加redirectUrl,但是如何找到以前的URL路径?

How can I redirect to the page I need? I have a loginBean which contains the user and password and I could add a redirectUrl but how do I find the previous url path?

推荐答案

Spring Security

Spring Security implements this logic for you in the AbstractAuthenticationProcessingFilter (typically using the concrete implementation of UsernamePasswordAuthenticationFilter) by using the SavedRequestAwareAuthenticationSuccessHandler (which uses the HttpSessionRequestCache under the covers). Since you have written a controller to authenticate (rather than using the built in support) you will need to implement this logic yourself. Rather than implementing all of the logic yourself, you can reuse the same classes Spring Security does.

例如,您的LoginController可能会更新如下:

For example, your LoginController might be updated as follows:

public class LoginController implements Serializable {
    // ... same as before ...
    private RequestCache requestCache = new HttpSessionRequestCache();

    public String loginUsingSpringAuthenticationManager() {
        // ... just as you had been doing ...

        if (authenticationResponseToken.isAuthenticated()) {
            HttpServletRequest request = (HttpServletRequest)         
              FacesContext.getCurrentInstance().getExternalContext().getRequest();
            HttpServletResponse response = (HttpServletResponse)         
              FacesContext.getCurrentInstance().getExternalContext().getResponse();

            SavedRequest savedRequest = requestCache.getRequest(request, response);

            return savedRequest.getRedirectUrl();
        }

        // ... same as you had ...
   }
}

这篇关于具有Spring安全性的JSF-登录后重定向到指定页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆