且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何将已通过身份验证的用户从登录页面重定向到主页

更新时间:2021-12-31 07:06:58

经过身份验证后,当我尝试访问登录页面时,它不会重定向我的主页.即使已经有登录用户,我也可以再次登录

Shiro或自定义Shiro用户过滤器均无意防止这种情况. Shiro没有为此提供内置设施.定制的Shiro用户过滤器仅在找到未经身份验证的用户时运行,而不是在找到已经经过身份验证的用户时运行.

Neither Shiro nor the custom Shiro user filter are intented to prevent that. Shiro doesn't have builtin facilities for this. The custom Shiro user filter runs only when an unauthenticated user is found, not when an already authenticated user is found.

防止已认证的用户直接访问登录页面是您的责任.根据业务需求,您可以执行以下操作:

Preventing an authenticated user from accessing the login page directly is your own responsibility. Depending on business requirements you can do the following:

  • 只允许它.也许用户只是想切换登录名.如果有必要,您可以有条件地显示一条消息,例如:

  • Just allow it. Perhaps the user just want to switch logins. You could if necessary conditionally show a message like:

<ui:fragment rendered="#{not empty request.remoteUser}">
    You are already logged-in as #{request.remoteUser}.
    By logging in as another user, you will be logged out.
</ui:fragment>
<h:form id="login">
    ...
</h:form>

  • 不允许,但要保留在同一页面上.有条件地隐藏登录表单并显示如下消息:

  • Don't allow it, but stay in the same page. Conditionally hide the login form and show a message like:

    <ui:fragment rendered="#{not empty request.remoteUser}">
        Hey, how did you end up here?
        You are already logged-in as #{request.remoteUser}!
    </ui:fragment>
    <h:form id="login" rendered="#{empty request.remoteUser}">
        ...
    </h:form>
    

    当然,请确保当用户已经登录时,您的Web应用程序没有任何登录链接.

    And, of course, make sure that your web application doesn't have anywhere a login link when the user is already logged in.

    不允许它并重定向到所需的目标页面.这又可以通过几种方式来完成.最干净的方法是使用Servlet过滤器.

    Don't allow it and redirect to the desired target page. This can in turn be done in several ways. Most clean approach is using a servlet filter.

    @WebFilter(urlPatterns = "/login.xhtml")
    public class LoginPageFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
    
            if (request.getRemoteUser() != null)) {
                response.sendRedirect(request.getContextPath() + "/home.xhtml"); // Redirect to home page.
            } else {
                chain.doFilter(req, res); // User is not logged-in, so just continue request.
            }
        }
    
        // Add/generate init() and destroy() with NOOP.
    }
    

    您也可以在preRenderView事件监听器中执行此操作. @PostConstruct可能为时已晚,因为此时响应可能已经提交.请注意,在没有任何形式反馈的情况下进行重定向可能会使最终用户感到困惑.在过滤器中,考虑传递一个附加参数,该附加参数应触发条件消息.或在preRenderView事件侦听器中,设置Flash范围内的消息.

    You can also do this in a preRenderView event listener. A @PostConstruct may be too late as the response may already be committed at that point. Note that redirecting without any form of feedback may be confusing for the enduser. In the filter, consider passing an additional parameter which should trigger a conditional message. Or in the preRenderView event listener, set a flash scoped message.