解决shiro自定义filter后,ajax登录无法登录,并且无法显示静态资源的问题
这个问题困扰了我一天,看了下面两个文章,豁然开朗:
https://www.cnblogs.com/gj1990/p/8057348.html
https://412887952-qq-com.iteye.com/blog/2392741
按照如下方法即可解决无法显示静态资源问题:
一、让springboot拦截器来接管静态资源,同时在shiroconfig中通过new方式注册过滤器
1、代码一
import java.util.Arrays; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /**
* SpringBoot管理器
*/
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer { private final Logger logger = LoggerFactory.getLogger(WebMvcConfiguration.class); @Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginRequiredInterceptor()).excludePathPatterns(Arrays.asList("/css/**", "/js/**","/img/**","/fonts/**"));
}
}
2、代码二
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; /**
* 登录拦截器
*
*
*/
public class LoginRequiredInterceptor extends HandlerInterceptorAdapter { private final Logger logger = LoggerFactory.getLogger(LoginRequiredInterceptor.class); @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.info(request.getRequestURI());
return super.preHandle(request, response, handler);
} @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
logger.info(request.getRequestURI());
super.afterCompletion(request, response, handler, ex);
}
}
三、shiro配置中使用new方式生成filter
filters.put("authc", new ExtendFormAuthenticationFilter());
filterChainDefinitionMap.put("/**", "user,authc");
四、自定义filter
import com.simon.common.util.R;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter; public class ExtendFormAuthenticationFilter extends FormAuthenticationFilter { private static final Logger log = LoggerFactory.getLogger(FormAuthenticationFilter.class); /**
* 表示当访问拒绝时是否已经处理了;如果返回true表示需要继续处理;如果返回false表示该拦截器实例已经处理了,将直接返回即可。
* onAccessDenied是否执行取决于isAccessAllowed的值,如果返回true则onAccessDenied不会执行;如果返回false,执行onAccessDenied
* 如果onAccessDenied也返回false,则直接返回,不会进入请求的方法(只有isAccessAllowed和onAccessDenied的情况下)
* */ @Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if(this.isLoginRequest(request, response)) {
if(this.isLoginSubmission(request, response)) {
if(log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
} return this.executeLogin(request, response);
} else {
if(log.isTraceEnabled()) {
log.trace("Login page view.");
} return true;
}
} else {
if(log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the Authentication url [" + this.getLoginUrl() + "]");
} this.saveRequestAndRedirectToLogin(request, response);
return false;
}
} /** * 当登录成功 * @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 { HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response; if (!"XMLHttpRequest".equalsIgnoreCase(httpServletRequest
.getHeader("X-Requested-With"))) {// 不是ajax请求
issueSuccessRedirect(request, response);
} else {
httpServletResponse.setCharacterEncoding("UTF-8");
PrintWriter out = httpServletResponse.getWriter(); //out.println("{\"success\":true,\"message\":\"登入成功\"}");
out.println(R.ok());
out.flush();
out.close();
}
return false;
} /** * 当登录失败 * @param token * @param e * @param request * @param response * @return */
@Override
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
if (!"XMLHttpRequest".equalsIgnoreCase(((HttpServletRequest) request)
.getHeader("X-Requested-With"))) {// 不是ajax请求
setFailureAttribute(request, e);
return true;
}
try {
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
String message = e.getClass().getSimpleName();
if ("IncorrectCredentialsException".equals(message)) {
out.println("{\"success\":false,\"message\":\"密码错误\"}");
} else if ("UnknownAccountException".equals(message)) {
out.println("{\"success\":false,\"message\":\"账号不存在\"}");
} else if ("LockedAccountException".equals(message)) {
out.println("{\"success\":false,\"message\":\"账号被锁定\"}");
} else {
out.println("{\"success\":false,\"message\":\"未知错误\"}");
}
out.flush();
out.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return false;
}
} 第二种方式就是“取消Filter自动注册,不会添加到FilterChain中“,方法如下:
一、定义过滤器,如上第四步
二、在shiroconfig中声明自定义FormAuthenticationFilter
@Bean
public ExtendFormAuthenticationFilter getLoginAdviceFilter(){
ExtendFormAuthenticationFilter filter=new ExtendFormAuthenticationFilter();
filter.setRememberMeParam("username");
filter.setPasswordParam("password");
//对应前端的checkbox的name = rememberMe
filter.setRememberMeParam("rememberMe");
filter.setLoginUrl(loginUrl);
return filter;
}
三、取消注册
@Bean
public FilterRegistrationBean registrationBean(ExtendFormAuthenticationFilter customFormAuthenticationFilter){
FilterRegistrationBean registration = new FilterRegistrationBean(customFormAuthenticationFilter);
registration.setEnabled(false);//怎么取消 Filter自动注册,不会添加到FilterChain中.
return registration;
}
通过以上步骤就实现了解决shiro自定义filter后,ajax登录无法登录,并且无法显示静态资源的问题
解决shiro自定义filter后,ajax登录无法登录,并且无法显示静态资源的问题的更多相关文章
- shiro 自定义filter
1.自定义登录filter package com.creatunion.callcenter.filter; import com.alibaba.fastjson.JSONObject; impo ...
- Shiro自定义realm实现密码验证及登录、密码加密注册、修改密码的验证
一:先从登录开始,直接看代码 @RequestMapping(value="dologin",method = {RequestMethod.GET, RequestMethod. ...
- shiro session过期后ajax请求跳转(转)
配置了 Shrio框架,session也集成进去了 ,发现问题session会话过期,点击页面,一直请求失败.本来想集成拦截器,过滤器,但是已经用了shiro框架,sessionDestroyed 方 ...
- 解决validaform先验证后 ajax提交
$(".myfroms").Validform({//form class btnSubmit:".submitLayer", 绑定提交按钮 tiptype:4 ...
- web项目中url-pattern改成'/'后,js、css、图片等静态资源(404)无法访问问题解决办法
感谢http://blog.csdn.net/this_super/article/details/7884383的文章 1.增加静态资源url映射 如Tomcat, Jetty, JBoss, Gl ...
- web项目中url-pattern改成'/'后,js、css、图片等静态资源(404)无法访问问题解决办法
感谢http://blog.csdn.net/this_super/article/details/7884383的文章 1.增加静态资源url映射 如Tomcat, Jetty, JBoss, Gl ...
- 解决Shiro+SpringBoot自定义Filter不生效问题
在SpringBoot+Shiro实现安全框架的时候,自定义扩展了一些Filter,并注册到ShiroFilter,但是运行的时候发现总是在ShiroFilter之前就进入了自定义Filter,结果当 ...
- shiro 返回json字符串 + 自定义filter
前言: 在前后端分离的项目中, 在使用shiro的时候, 我们绝大部分时候, 并不想让浏览器跳转到那个页面去, 而是告诉前端, 你没有登录, 或者没有访问权限. 那这时候, 我们就需要返回json字符 ...
- Shiro权限管理框架(五):自定义Filter实现及其问题排查记录
明确需求 在使用Shiro的时候,鉴权失败一般都是返回一个错误页或者登录页给前端,特别是后台系统,这种模式用的特别多.但是现在的项目越来越多的趋向于使用前后端分离的方式开发,这时候就需要响应Json数 ...
随机推荐
- 为什么说ArrayList是线程不安全的?
一.概述 对于ArrayList,相信大家并不陌生.这个类是我们平时接触得最多的一个列表集合类. 面试时相信面试官首先就会问到关于它的知识.一个经常被问到的问题就是:ArrayList是否是线程安全的 ...
- JDBC超时设置【转】
恰当的JDBC超时设置能够有效地减少服务失效的时间.本文将对数据库的各种超时设置及其设置方法做介绍. 真实案例:应用服务器在遭到DDos攻击后无法响应 在遭到DDos攻击后,整个服务都垮掉了.由于第四 ...
- BeautifulSoup的简单用法
官方文档加载比较慢(估计是我党的原因) https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#find-parents ...
- [bzoj4942] [洛谷P3822] [NOI2017] 整数
题目链接 https://www.luogu.org/problemnew/show/P3822 想法 这个啊,就是线段树哇 最初的想法是每位一个节点,然后进位.退位找这一位前面第一个0或第一个1,然 ...
- 手撸一个SpringBoot的Starter,简单易上手
前言:今天介绍一SpringBoot的Starter,并手写一个自己的Starter,在SpringBoot项目中,有各种的Starter提供给开发者使用,Starter则提供各种API,这样使开发S ...
- 我的一个git(码云)之旅
合作开发项目,你就会用到git,现在码云比较简单,因为是中文化界面,学习起来难度比较低,又支持5人以下项目免费,所以学习码云更好入手一点. 下面的东西适合一些个基础比较低的用户学习,因为我就是啊... ...
- 深入源码解析spring aop实现的三个过程
Spring AOP的面向切面编程,是面向对象编程的一种补充,用于处理系统中分布的各个模块的横切关注点,比如说事务管理.日志.缓存等.它是使用动态代理实现的,在内存中临时为方法生成一个AOP对象,这个 ...
- C#系列之算数运算符(四)
今天,我将做一个算术运算符++和--的笔记以及一元运算符和二元运算符同时存在怎么计算的笔记 ++:分为前加加和后加加,但是最后结果都是+1: --:分为前减减和后减减,但是最后结果都是-1: 例如: ...
- demon病毒样本分析
1. 简介 该样本是前几周爆发的THINKPHP漏洞中,被批量上传的一个病毒样本.如图所示. 2. 分析 该样本未经混淆,加壳,所以直接拖到IDA中即可分析. 首先从main函数开始.做一些初始化的函 ...
- ros机器人之动作(二)
前面我们实现了动作的定义,接下来实现动作的功能 实现一个基本的动作服务器 准备好所需的动作定义后就可以开始编写代码了.动作和话题一样,都是使用回调机制,即回调函数会在收到消息时被唤醒和调用. 例:si ...