How can I redirect requests to a configured Shiro loginUrl if the user is already authenticated?

alan picture alan · Jan 2, 2013 · Viewed 9.1k times · Source

I have a webapp using Shiro for authentication. The relevant parts of the web.xml and shiro.ini are:

<listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>ShiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>ShiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

and

[main]
authc.loginUrl = /authoring/login.html
authc.successUrl  = /authoring
logout.redirectUrl = /authoring/login.html

[users]
foo = foo

[urls]
/authoring/logout = logout
/authoring/** = authc

Shiro correctly intercepts all requests from non-authenticated clients and redirects to the configured loginUrl (and then forwards them on to the requested page after successful authentication). What I'd like to have happen is, if an authenticated client makes an explicit request to /authoring/login.html, redirect that to /authoring. This would ONLY happen if the client is authenticated.

For example, think of how Gmail works - trying to access mail.google.com (or even https://accounts.google.com/ServiceLogin) when you've already logged in redirects you to the inbox. Is this possible with Shiro out of the box? If not, what's the right way to implement it?

Answer

Alex Edwards picture Alex Edwards · Jan 2, 2013

You could handle the login request yourself or using your framework, you would need to change your shiro.ini to use a PassThruAuthenticationFilter

authc = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter

You could now check if the user is logged in and redirect if true:

Subject currentUser = SecurityUtils.getSubject();
if(currentUser.isAuthenticated()){
    //redirect
}else{
    AuthenticationToken token =  new UsernamePasswordToken(username, password);
    currentUser.login(token);
    WebUtils.redirectToSavedRequest(request, response, "index.xhtml");
}

This isn't an totally out of the box solution. I am not certain if you can get the success url outside of the authentication, you could manually redirect WebUtils.issueRedirect(req, resp, url)