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

标签 jsf-2 servlet-filters shiro

我正在使用 Apache Shiro 开发 JSF 应用程序。我使用 Shiro 验证用户并将她重定向到主页,这没有问题。在我尝试访问登录页面时进行身份验证后,它不会将我重定向到主页。即使已经有登录用户,我也可以再次登录。我在做Programmatic Login正如 BalusC 在他的博客文章中提到的那样。

[main]
credentialsMatcher = org.apache.shiro.authc.credential.PasswordMatcher
myRealm = com.example.security.myRealm
myRealm.credentialsMatcher = $credentialsMatcher
securityManager.realms = $myRealm
user = com.example.web.filter.FacesAjaxAwareUserFilter
user.loginUrl = /login.xhtml

[urls]
/login.xhtml = user

此过滤器是从博客文章中编写的。
public class FacesAjaxAwareUserFilter extends UserFilter {

private static final String FACES_REDIRECT_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
        + "<partial-response><redirect url=\"%s\"></redirect></partial-response>";

@Override
protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
    HttpServletRequest req = (HttpServletRequest) request;
    if ("partial/ajax".equals(req.getHeader("Faces-Request"))) {
        response.setContentType("text/xml");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().printf(FACES_REDIRECT_XML, req.getContextPath() + getLoginUrl());
    }
    else {
        super.redirectToLogin(request, response);
    }
}

}

有什么问题,如果用户已经过身份验证,我该如何重定向用户?

编辑:现在,如果用户已通过身份验证,我将使用 PostConstruct 注释进行重定向。我愿意接受任何好的解决方案。

最佳答案

After the authentication when I try to access login page, it doesn't redirect me the homepage. I can login again even when there is already loggedin user


Shiro 和自定义 Shiro 用户过滤器都无意阻止这种情况。 Shiro 没有为此提供内置设施。自定义 Shiro 用户过滤器仅在找到未经身份验证的用户时运行,而不是在找到已通过身份验证的用户时运行。
防止经过身份验证的用户直接访问登录页面是您自己的责任。根据业务需求,您可以执行以下操作:
  • 就让它吧。也许用户只是想切换登录。如有必要,您可以有条件地显示如下消息:
      <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>
    
  • 不允许它,但保持在同一页面。有条件地隐藏登录表单并显示如下消息:
      <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 应用程序没有任何登录链接。
  • 不允许它并重定向到所需的目标页面。这又可以通过多种方式完成。最干净的方法是使用 servlet 过滤器。
      @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.
      }
    
    You can also do this in a preRenderView event listener . @PostConstruct可能为时已晚,因为此时可能已经提交了响应。请注意,在没有任何形式反馈的情况下进行重定向可能会让最终用户感到困惑。在过滤器中,考虑传递一个应该触发条件消息的附加参数。或在 preRenderView事件监听器,设置一个 Flash 范围的消息。
  • 关于jsf-2 - 如何将已通过身份验证的用户从登录页面重定向到主页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20283058/

    相关文章:

    spring - 如何保护 Grails 中的所有 REST 请求和响应

    jsf-2 - primefaces 对话框不工作

    JSF HTML5 标签教程/指南?

    java - Apache shiro Web 应用程序索引页面作为默认页面

    java - 覆盖 HttpServletRequest 中的 getContextPath(用于 URL 重写)

    shiro - 在 apache shiro 上为主题添加信息

    jsf - 谷歌图表 : How to pass the datatable from Java files to JavaScript

    jsf - java.lang.VerifyError : org/primefaces/behavior/confirm/ConfirmBehaviorHandler Wrong return type in function

    java - 如何运行 servlet 过滤器?

    grails - 使用Shiro插件保护Grails应用程序中部分而非全部页面的安全