Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to redirect already authenticated user from login page to home page

I'm developing JSF application with Apache Shiro. I autenticate the user with Shiro and redirect her to home page there is no problem with that. 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. I'm doing Programmatic Login as BalusC mentioned in his blog post.

[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

This filter is written from the blog post.

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);
    }
}

}

What is the problem and how can I redirect the user if she is already authenticated?

EDIT: For now I'm using PostConstruct annotation to redirect if the user is already authenticated. I'm open to any good solution.

like image 229
molgun Avatar asked Nov 29 '13 10:11

molgun


People also ask

How do I redirect a user after login?

Using the available dropdown, select the user for whom you wish to specify the redirect URLs. Then manually insert the after-login URL in the URL field. Then, if you want, you can add the after-logout URL in the Logout URL field. When you're done, click on the Add username rule button below.

How do I redirect a homepage to wordpress after login?

WP Login and Logout RedirectUpon installation, you'll find the new Redirect Options menu in your sidebar. Click it, and you'll see two boxes: Login Redirect URL and Logout Redirect URL. Put the URL you want in and click Save Changes, and you're done.

How do I redirect a requested URL after login?

The most common ways to implement redirection logic after login are: using HTTP Referer header. saving the original request in the session. appending original URL to the redirected login URL.


1 Answers

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

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>
    

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

  • 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.
      }
    

    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.

like image 51
BalusC Avatar answered Jan 01 '23 20:01

BalusC