How to redirect an authenticated user from the login page to the main page

I am developing a JSF application with Apache Shiro. I assure the user of Shiro and redirect it to the home page, there is no problem with this. After authentication, when I try to access the login page, it does not redirect me to the home page. I can log in again, even if the user is already registered. I am doing a 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 a 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 has already authenticated?

EDIT:. Now I use the PostConstruct annotation to redirect if the user has already authenticated. I am open to any good decision.

+6
source share
1 answer

After authentication, when I try to access the login page, it does not redirect me to the home page. I can log in again even if the user has already registered

Neither Shiro nor the Shiro user filter are intended to prevent this. Shiro has no built-in tools for this. The Shiro custom user filter is only triggered when it detects a failed user, and not when it detects a user who has already been authenticated.

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

  • Just let it go. Perhaps the user just wants to switch to logins. If necessary, you could 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> 
  • Do not allow, but stay on one page. Conditionally hide the login form and show a message, for example:

     <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 your web application does not have a single login link when the user is already registered.

  • Do not allow it and redirect to the desired landing page. This, in turn, can be done in several ways. The cleanest approach is to use 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 the preRenderView event preRenderView . A @PostConstruct may be too late, as the answer may already be fixed at that point. Please note that redirecting without any feedback can be confusing for the end user. In the filter, we consider the possibility of passing an additional parameter, which should cause a conditional message. Or, in the preRenderView event preRenderView set a flash message.

+7
source

Source: https://habr.com/ru/post/959035/


All Articles