这个问题困扰了我一天,看了下面两个文章,豁然开朗:

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登录无法登录,并且无法显示静态资源的问题的更多相关文章

  1. shiro 自定义filter

    1.自定义登录filter package com.creatunion.callcenter.filter; import com.alibaba.fastjson.JSONObject; impo ...

  2. Shiro自定义realm实现密码验证及登录、密码加密注册、修改密码的验证

    一:先从登录开始,直接看代码 @RequestMapping(value="dologin",method = {RequestMethod.GET, RequestMethod. ...

  3. shiro session过期后ajax请求跳转(转)

    配置了 Shrio框架,session也集成进去了 ,发现问题session会话过期,点击页面,一直请求失败.本来想集成拦截器,过滤器,但是已经用了shiro框架,sessionDestroyed 方 ...

  4. 解决validaform先验证后 ajax提交

    $(".myfroms").Validform({//form class btnSubmit:".submitLayer", 绑定提交按钮 tiptype:4 ...

  5. web项目中url-pattern改成'/'后,js、css、图片等静态资源(404)无法访问问题解决办法

    感谢http://blog.csdn.net/this_super/article/details/7884383的文章 1.增加静态资源url映射 如Tomcat, Jetty, JBoss, Gl ...

  6. web项目中url-pattern改成'/'后,js、css、图片等静态资源(404)无法访问问题解决办法

    感谢http://blog.csdn.net/this_super/article/details/7884383的文章 1.增加静态资源url映射 如Tomcat, Jetty, JBoss, Gl ...

  7. 解决Shiro+SpringBoot自定义Filter不生效问题

    在SpringBoot+Shiro实现安全框架的时候,自定义扩展了一些Filter,并注册到ShiroFilter,但是运行的时候发现总是在ShiroFilter之前就进入了自定义Filter,结果当 ...

  8. shiro 返回json字符串 + 自定义filter

    前言: 在前后端分离的项目中, 在使用shiro的时候, 我们绝大部分时候, 并不想让浏览器跳转到那个页面去, 而是告诉前端, 你没有登录, 或者没有访问权限. 那这时候, 我们就需要返回json字符 ...

  9. Shiro权限管理框架(五):自定义Filter实现及其问题排查记录

    明确需求 在使用Shiro的时候,鉴权失败一般都是返回一个错误页或者登录页给前端,特别是后台系统,这种模式用的特别多.但是现在的项目越来越多的趋向于使用前后端分离的方式开发,这时候就需要响应Json数 ...

随机推荐

  1. kubernetes concepts -- Termination Of Pod

    Pods are the smallest deployable units of computing that can be created and managed in Kubernetes. W ...

  2. 如何通过Java8的方式去统计程序执行时间?

    代码如下所示 import java.time.Duration; import java.time.Instant; import java.util.concurrent.TimeUnit; pu ...

  3. matplotlib 散点图

    一.特点 离散的数据,查看分布规律,走向趋势 二.使用 1.核心 plt.scatter(x, y) # x为x轴的数据,可迭代对象,必须是数字 # y为y轴的数据,可迭代对象,必须是数字 # x和y ...

  4. Vue 例子

    一.简单音乐播放器 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  5. Java入门 - 面向对象 - 05.封装

    原文地址:http://www.work100.net/training/java-encapsulation.html 更多教程:光束云 - 免费课程 封装 序号 文内章节 视频 1 概述 2 封装 ...

  6. 开发环境Vue访问后端接口教程(前后端分离开发,端口不同下跨域访问)

    原理:开发环境下的跨域:在node.js上实现请求转发,vue前端通过axios请求到node.js上,node.js将请求转发到后端,反之.响应也是,先到node.js上,然后转发vue-cil项目 ...

  7. python条件与循环-循环

    1 while语句 while用于实现循环语句,通过判断条件是否为真,来决定是否继续执行. 1.1 一般语法 语法如下: while expression: suite_to_repeat 1.2 计 ...

  8. Deep server from scratch

    Deep server from scratch 1.install Ubuntu16.04 via flash2.wired Network by Ruijie3.install google4.S ...

  9. CF-528D Fuzzy Search(FFT字符串匹配)

    Fuzzy Search 题意: 给定一个模式串和目标串按下图方式匹配,错开位置不多于k 解题思路: 总共只有\(A C G T\)四个字符,那么我们可以按照各个字符进行匹配,比如按照\(A\)进行匹 ...

  10. c++中多文件的组织

    参考书目:visual c++ 入门经典 第七版 Ivor Horton著 第八章 根据书中例子学习使用类的多文件项目. 首先要将类CBox定义成一个连贯的整体,在CBox.H文件中写入相关的类定义, ...