Shiro记住我无效,被拦截;

Shiro记住我无效,被拦截

场景描述:

       Shiro的记住我功能就是登录的时候,选择了记住当前用户的选项来登录,关闭浏览器之后,在登录信息存活期间再次访问项目里的某个页面可以直接访问。可以在程序中对某些敏感操作进行判断是否为通过记住我登录的用户,从而进行其他一系列限制操作。

       在按照网上的配置配置完之后,发现记住我之后再次访问其他功能时,会被拦截,并且不会通过项目中debug打了断点的部分,直接被跳转到未登录处理的登录页面,而且我查了很多很多的相关配置文档,都试了就是实现不了。事实上是取到了cookie中保存的信息,被拦截后的页面地址栏如下:

http://localhost:xxxx/xxxx/login.do;jsessionid=4D328B61960C713B2F563385F85EC43C

原因:

        通过询问其他朋友,发现是因为实体类没有序列化,Shiro是将实体对象序列化保存到本地cookie中,但是很多文档都没有提及这一点,或许是自己没有这个意识。

解决办法:

       更改之前:

public class User  {
...
}

        更改之后:

public class User implements Serializable {
...
}

     再次测试的时候,发现通过debug就会走项目中的打了断点的地方。

设置自定义拦截器将本地用户放入到session中

参考文章地址:https://blog.csdn.net/u011277123/article/details/70214599

场景描述:

       其他所有的controller中涉及到用户的都是从session中获取,但是通过记住我登录的用户的用户信息是放在本地的cookie中,然后shiro获取后是将其放入的subject中,通过subject可以获取记住我用户的信息,但是我的jsp页面中通过el标签获取了用户对象并展示在前台页面,所以干脆我就做了一个自定义过滤器,所有访问都需要走一遍这个过滤器,如果是通过记住我登录的,就把本地获取的用户对象放入到session中,配置如下:

java类:

public class MyRememberFilter extends FormAuthenticationFilter {
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        Subject subject=getSubject(request,response);
        // 如果是记住我登录的,则需要处理一下
        // isRemembered为true、isAuthenticated为false
        if(!subject.isAuthenticated() && subject.isRemembered()){
            // 通过记住我第一次进程序,并且保存的principal中有内容,添加用户到session
            if(subject.getSession().getAttribute("user")==null && subject.getPrincipal() != null){
                subject.getSession().setAttribute("user",subject.getPrincipal());
            }
        }
        return subject.isAuthenticated() || subject.isRemembered();
    }
}

 

applicationContext.xml中的bean引入shiro过滤器配置:

	<!--自定义全局过滤器-->
	<bean id="MyRememberFilter" class="com.xxx.xxx.shrio.MyRememberFilter"></bean>	
    ...
    <!-- web.xml中shiro的filter对应的bean -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        ...
		<!--在shiro中使用自定义过滤器-->
		<property name="filters">
			<util:map>
				<entry key="MyRemember" value-ref="MyRememberFilter"></entry>
			</util:map>
		</property>
		<!-- 指定过滤器
            Anon:不指定过滤器,这个过滤器是空的,什么都没做,跟没有一样。
            Authc:验证,这些页面必须验证后才能访问,也就是我们说的登录后才能访问。
            user:验证+记住我
         -->
		<property name="filterChainDefinitions">
			<value>
				<!--静态资源-->
				/static/** = anon
				<!--链接-->
				/login.do=anon
				/toLogin.do=anon
				/** = user
                <!--自定义过滤器-->
                /** = MyRemember
			</value>
		</property>
	</bean>
</beans>

        我只放了相关的配置,无关的都省略掉了;

by the way:

1.Shiro的其他配置建议看这位博主文章,我认为是写的最工整易懂的:https://blog.csdn.net/u012737182/article/category/6489910

2.序列化与反序列化的相关文章:https://blog.csdn.net/qq_27093465/article/details/78544505

### 创建自定义 'RememberMe' 过滤器 为了实现在 Apache Shiro 中创建自定义的 'RememberMe' 功能过滤器,需要遵循几个关键步骤。 #### 添加 Maven 依赖项 在项目的 `pom.xml` 文件中加入必要的 Shiro 依赖项以支持核心功能和 Spring 集成: ```xml <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> ``` 这些依赖项提供了构建自定义 RememberMe 解决方案所需的基础组件[^2]。 #### 自定义 Filter 实现 通过继承 `FormAuthenticationFilter` 类并重写相应方法来自定义过滤器行为。这允许更细粒度地控制登录流程中的记住我逻辑: ```java import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; public class CustomRememberMeFilter extends FormAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { // 自定义处理逻辑... return super.onAccessDenied(request, response); } @Override protected boolean isLoginSubmission(ServletRequest request) { // 判断是否提交了登录表单 return super.isLoginSubmission(request); } } ``` 此代码片段展示了如何扩展默认的身份验证过滤器来添加额外的行为[^3]。 #### 注册自定义过滤器到 Shiro 配置 最后,在应用程序上下文中注册新创建的过滤器实例,并将其关联至 URL 路径模式以便应用该规则。通常是在配置类中完成这项工作: ```java @Configuration public class ShiroConfig { @Bean(name = "shiroFilter") public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); // ...其他路径映射... // 将自定义过滤器应用于指定URL filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/**", "customRememberMe"); bean.setSecurityManager(securityManager); bean.setFilterChainDefinitionMap(filterChainDefinitionMap); // 设置自定义过滤器 Map<String, Filter> filters = new HashMap<>(); filters.put("customRememberMe", customRememberMeFilter()); bean.setFilters(filters); return bean; } @Bean public CustomRememberMeFilter customRememberMeFilter(){ return new CustomRememberMeFilter(); } } ``` 这段配置说明了怎样把之前定义好的过滤器集成进来,并指定了它应该作用于哪些请求路径上[^1]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值