解决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数 ...
随机推荐
- 出现An App ID with Identifier 'com.XXX.XXX’ is not available. Please enter a different string.
解决方法: 1.移除钥匙串中的开发证书,重新导入, 完全关闭Xcode; 2.再次打开Xcode,通过 Preferences - View Details - download 新的证书: 3.选择 ...
- git 查看修改账号密码
git config user.name 查看用户名 git config user.email 查看用户邮箱 修改用户名和邮箱的命令 git config --glo ...
- python常用内置模块-random模块
random模块:用于生成随机数 '''关于数据类型序列相关,参照https://www.cnblogs.com/yyds/p/6123692.html''' random() 随机获取0 到1 之间 ...
- 玩转Django2.0---Django笔记建站基础十一(一)(音乐网站开发)
第十一章 音乐网站开发 本章以音乐网站项目为例,介绍Django在实际项目开发中的应用,该网站共分为6个功能模块分别是:网站首页.歌曲排行榜.歌曲播放.歌曲点评.歌曲搜索和用户管理. 11.1 网站需 ...
- Java的String类常用方法
一.构造函数 String(byte[ ] bytes):通过byte数组构造字符串对象. String(char[ ] value):通过char数组构造字符串对象. String(Sting or ...
- 1.Vue初始及相关Vue核心组件
1.Vue官方文档 官网文档:https://cn.vuejs.org/v2/guide/ 2.Vue-cli官方文档(脚手架) 官网文档:https://cli.vuejs.org/zh/guide ...
- laravel 队列服务使用总结
laravel 队列服务使用总结 使用步骤 配置队列驱动 //env文件,有的版本是QUEUE_DRIVER QUEUE_CONNECTION=database 迁移队列需要的数据表,在数据库中生成j ...
- Docker扩展内容之容器开机自启
前言 部署项目服务器时,为了应对停电等情况影响正常web项目的访问,会把Docker容器设置为开机自动启动. 在使用docker run启动容器时,使用--restart参数来设置,具体参数如下详解 ...
- HDFS NameNode重启优化
http://tech.meituan.com/namenode-restart-optimization.html 一.背景 在Hadoop集群整个生命周期里,由于调整参数.Patch.升级等多种场 ...
- 16、ISDN
ISDN:综合业务数据网 分类:1.宽带ISDN:基本上被淘汰2.窄带ISDN:用于备份链路,速率比较低 ISDN的起源和优点 ISDN能够提供声音.视频.数据等传输业务 ISDN的两种服务方式ISD ...