shiro为什么拦截不存在的请求

spring整合shiro后,在登陆认证之前会拦截不存在的请求:

这是我的loginrul配置:<property name="loginUrl" value="/signIn" />
项目启动后我输入一个不存在的地址:http://localhost:8080/demo/abc123,也会进入loginurl配置的signIn,demo是我的项目名,dbc123是一个不存在的请求。



web.xml配置:



    <!-- 加载spring容器 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/applicationContext-*.xml</param-value>
    </context-param>
    <!-- spring内监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 防止spring内存溢出监听器 -->
    <listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>




    <!-- post乱码过虑器 -->
    <!-- 除了加过滤器,由于tomcat默认编码ISO-8859-1,还需要修改 %tomcat%/conf/server.xml Connector 标签加属性 URIEncoding="UTF-8" -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>



    <!-- shiro的filter -->
    <!-- shiro过虑器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 -->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <!-- 设置true由servlet容器控制filter的生命周期 -->
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>







    <!-- springmvc前端控制器,rest配置 -->
    <servlet>
        <servlet-name>springmvc_rest</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc_rest</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <!-- 静态资源解析 -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/script/*</url-pattern>
        <url-pattern>/style/*</url-pattern>
        <url-pattern>/WEB-INF/html/*</url-pattern>
        <url-pattern>/login.html</url-pattern>
    </servlet-mapping>

spring-shiro配置:


    <!-- web.xml中shiro的filter对应的bean -->
    <!-- Shiro 的Web过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

        <property name="securityManager" ref="securityManager" />
        <!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
        <property name="loginUrl" value="/signIn" />
        <!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->
        <property name="successUrl" value="/index"/>

        <!-- 自定义filter配置 -->
        <property name="filters">
            <map>
                <!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中-->
                <entry key="authc" value-ref="formAuthenticationFilter" />
            </map>
        </property>



        <!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
        <property name="filterChainDefinitions">
            <value>
                <!-- 对静态资源设置匿名访问 -->
                /script/**       = anon
                /style/**        = anon
                /WEB-INF/html/** = anon
                <!--/login.html      = anon-->


                <!-- 请求 logout.action地址,shiro去清除session-->
                /logout = logout


                <!-- /** = authc 所有url都必须认证通过才可以访问-->
                /** = authc
            </value>
        </property>
    </bean>



    <!-- securityManager安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="ssmRealm" />
        <property name="sessionManager" ref="sessionManager" />
    </bean>



    <!-- realm -->
    <bean id="ssmRealm" class="com.shiro.realm.SsmRealm"></bean>



    <!-- 会话管理器 -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="sessionIdUrlRewritingEnabled" value="false" />
        <!-- session的失效时长,单位毫秒 -->
        <property name="globalSessionTimeout" value="600000"/>
        <!-- 删除失效的session -->
        <property name="deleteInvalidSessions" value="true"/>
    </bean>


    <!-- 自定义form认证过虑器 -->
    <!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
    <bean id="formAuthenticationFilter" class=" com.shiro.filter.CustomFormAuthenticationFilter"></bean>

CustomFormAuthenticationFilter.java:

public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {


    /**
     * 认证成功跳转到指定地址
     * @param token
     * @param subject
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {

        WebUtils.getAndClearSavedRequest(request);
        WebUtils.redirectToSavedRequest(request,response,"/index");

        return false;
    }
}

我大概知道问题是出在shiro的拦截器,可是我不明白为什么shiro拦截器会拦截不存在的请求,此时应该是404;
希望有了解过的人抽点时间帮我参考下,非常感谢!

阅读 4.3k
1 个回答

没做机测,发表下我的想法,这应该和访问url有关系,abc123不一定是path,也可以参数${}类似这种形式,这样还是在访问你的工程,你设置的是/**=auth 应该会去校验权限,你试试多测试别的url,会不会出现。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题