Shiro doesn't redirect to unauthorizedUrl w/invalid login - Shiro with Spring and Tiles

懵懂的女人 提交于 2019-12-09 22:34:56

问题


I'm using Spring MVC, Tiles and Shiro.

This is how my unauthorizedUrl property is configured: <property name="unauthorizedUrl" value="/unauthorized"/>

My expectation is that when MyAuthorizingRealm finds invalid credentials, that Shiro will redirect to /unauthorized.

But, that doesn't happen for me on form submission. I have a login @Controller that is mapped to handle GET and POST actions for /login. For accesses to the url /lists the login form is displayed. So it seems to work in one case but not the other.

@Controller
@RequestMapping(value = "/login")
public class LoginController {

    @RequestMapping(method = RequestMethod.GET)
    public String getLoginFormView(Model model) {
        return "login";
    }

    // if this method doesn't exist a Post not supported exception is thrown
    @RequestMapping(method = RequestMethod.POST)
    public String handlePost() {
        return "this view doesn't exist";
    }
}

Even if I throw AuthenticationException from MyAuthorizingRealm.doGetAuthenticationInfo() I still can't get Shiro to redirect to /unauthorized. It always ends up continuing with the filter chain and executes the POST method in the @Controller; and of course I expect a redirect instead.

Here is my webapp-context.xml: http://pastebin.com/XZaCKqEC

And here is my web.xml: http://pastebin.com/5H81Tm8A

Following is some TRACE log output from Shiro. Shiro works when you try to access /lists. But, when the login form is submitted the redirect to /unauthorized never happens. Note, the login submission is detected: http://pastebin.com/ZEK3CTdJ

So, the login submission is detected but the original filter chain is executed anyway instead of redirecting to /unauthorized

I'm stumped. Many thanks for any help and if you need more info please let me know.


回答1:


I think I see two problems:

1) Your pastebin for your spring xml does not show the SecurityManager being configured with your realm. I.e. it needs to look like this:

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="myRealm"/>
</bean>

2) You're setting up a Spring MVC controller to perform authentication, which implies you want to control when subject.login is called and not rely on Shiro's built-in FormAuthenticationFilter (authc).

If you do this, you will need to redefine the authc filter to be a PassThruAuthenticationFilter.

This allows the request to 'pass through' the filter chain to your Login view/controller where you are responsible for calling subject.login

You can do that in your spring.xml by setting the filters property and using authc as the name for your configured filter:

<bean id="passthruAuthcFilter" class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter">
    <property name="loginUrl" value="/login"/>
</bean>

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    ...
   <property name="filters">
       <util:map>
           <entry key="authc" value-ref="passthruAuthcFilter"/>
       </util:map>
   </property>
   ...
</bean>

Also, as a tip, you might want to use Shiro's WebUtils to redirect the end-user to the url they originally attempted before being redirected to login. Shiro's FormAuthenticationFilter does this automatically, but when you perform the login yourself, you're responsible for doing this redirect if it is desired.

For example, in your LoginController's handlePost method:

subject.login(authcToken);
WebUtils.redirectToSavedRequest(request, response, yourFallbackUrlIfThereIsntASavedRequest);
return null; //tells Spring MVC you've handled the response, and not to render a view


来源:https://stackoverflow.com/questions/10303464/shiro-doesnt-redirect-to-unauthorizedurl-w-invalid-login-shiro-with-spring-an

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!