shiro异步请求返回JSON响应
shiro异步请求返回JSON响应
需求1:当shiro请求资源,但是没有进行认证时,默认是进行重定向,现在需要返回JSON响应。注意异步请求,服务器重定向后,ajax拿到的是浏览器重定向后的到的页面源码。
解决2: 自定义FormAuthenticationFilter。覆盖onAccessDenied方法。返回JSON字符串。并将自定义的过滤器添加到ShiroFilterFactoryBean,键的名称为authc。
需求2:ShiroFilterFactoryBean用注解时,过滤的urls被写死在代码中,需要将urls的配置放到配置文件中。
解决2:
方法1:ShiroFilterFactoryBean不使用注解方法,而是xml配置注入。@ImportResource("classpath:shiro/shiro-config.xml")
方法2:自己通过shiro的Ini类加载ini配置文件。读取自定义的urls。
步骤
自定义 authc 对应过滤器 FormAuthenticationFilter。覆盖 onAccessDenied 方法返回JSON响应。
将自定义过滤器添加到 ShiroFilterFactoryBean。名称为 authc 。
ResultFormAuthenticationFilter
package com.mozq.shiro.shiro01.config;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
@Slf4j
public class ResultFormAuthenticationFilter extends FormAuthenticationFilter {
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
if (isLoginRequest(request, response)) {
if (isLoginSubmission(request, response)) {
if (log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
}
return executeLogin(request, response);
} else {
if (log.isTraceEnabled()) {
log.trace("Login page view.");
}
//allow them to see the login page ;)
return true;
}
} else {
if (log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the " +
"Authentication url [" + getLoginUrl() + "]");
}
if(isAjaxRequest(request)){
saveRequest(request);
writeResult(response);
return false;
}
//saveRequestAndRedirectToLogin(request, response);
return false;
}
}
private boolean isAjaxRequest(ServletRequest request){
return request instanceof HttpServletRequest && "XMLHttpRequest".equalsIgnoreCase(((HttpServletRequest)request).getHeader("X-Requested-With"));
}
private void writeResult(ServletResponse servletResponse){
if(servletResponse instanceof HttpServletResponse){
HttpServletResponse response = (HttpServletResponse) servletResponse;
HashMap<String, String> result = new HashMap<>();
result.put("code", "401");
result.put("message","未登录");
try {
response.setHeader("Content-Type", "application/json;charset=UTF-8");
response.getWriter().write(JSONObject.toJSONString(result));
response.getWriter().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.yuantiao.smartcardms.config.shiro;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
import java.util.HashMap;
import java.util.Map;
/**
* @description:
* @author: changzhou.xie@yuantiaokj.com
* @date: 2019/11/1 14:14
*/
@Configuration
public class ShiroConfig {
//自定义 org.apache.shiro.realm.Realm
@Bean
public Realm realm(){
//IniRealm iniRealm = new IniRealm("classpath:user.ini");
SysUserRealm realm = new SysUserRealm();
return realm;
}
//定义 org.apache.shiro.mgt.SecurityManager
@Bean
public SecurityManager securityManager(Realm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
//定义 org.apache.shiro.spring.web.ShiroFilterFactoryBean
/* @Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//过滤的路径
Map<String, String> map = new HashMap<>();
map.put("/**", "authc");
map.put("/user/login/pc", "anon");//放行登录相关接口
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
shiroFilterFactoryBean.setLoginUrl("/login.html");//登录页面
return shiroFilterFactoryBean;
}*/
}
使用配置文件来创建ShiroFilterFactoryBean
package com.yuantiao.smartcardms;
import org.apache.catalina.connector.Connector;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ImportResource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* SpringBoot项目启动类
*/
@SpringBootApplication
@EnableScheduling/* 开启定时任务 */
@MapperScan("com.yuantiao.smartcardms.dao.mapper")
@ImportResource("classpath:shiro/shiro-config.xml")
public class SmartcardMsApplication {
public static void main(String[] args) {
SpringApplication.run(SmartcardMsApplication.class, args);
}
/**
* CORS跨域请求解决403
* @return
*/
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
return corsConfiguration;
}
/**
* 跨域请求COOKIES携带SessionId
* @return
*/
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
/**
* 请求链接[]{}非法字符
* @return
*/
@Bean
public TomcatServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers((Connector connector) -> {
connector.setProperty("relaxedPathChars", "\"<>[\\]^`{|}");
connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
});
return factory;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="filterChainDefinitionMap" >
<!-- 用props无法保证资源是按照顺序加载到filterChainDefinitionMap的,会有问题 -->
<!--<props>-->
<!--<prop key="/user/add">anon</prop>-->
<!--<prop key="/user/delete">roles[laoban]</prop>-->
<!--<prop key="/user/login/pc">anon</prop>-->
<!--<prop key="/user/logout">anon</prop>-->
<!--<prop key="/**">authc</prop>-->
<!--</props>-->
<map>
<entry key="/user/login/pc" value="anon"/>
<entry key="/**" value="authc"/>
</map>
</property>
<property name="loginUrl" value="/login.html"/>
<property name="securityManager" ref="securityManager"/>
<property name="filters">
<map>
<entry key="authc">
<bean class="com.yuantiao.smartcardms.config.shiro.ResultFormAuthenticationFilter"/>
</entry>
</map>
</property>
</bean>
</beans>
错误
<property name="filterChainDefinitionMap" >
<value>
/card.html = anon
/** = authc
</value>
</property>
<!--
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.util.Map' for property 'filterChainDefinitionMap': no matching editors or conversion strategy found
看到网上很多filterChainDefinitionMap这种写,但是一配置直接报错。value指定的是字符串,而filterChainDefinitionMap是一个LinkedHashMap对象。完全无法这样配置。
-->
bugs
jquery-3.1.1.min.js:4 POST http://localhost:9000/smartcard/user/login/pc 415
请求头:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Set-Cookie: JSESSIONID=080D2E469D78CD39C88AE54950B6640D; Path=/smartcard; HttpOnly
Set-Cookie: rememberMe=deleteMe; Path=/smartcard; Max-Age=0; Expires=Sat, 02-Nov-2019 02:32:54 GMT
shiro异步请求返回JSON响应的更多相关文章
- springmvc通过ajax异步请求返回json格式数据
jsp 首先创建index.jsp页面 <script type="text/javascript"> $(function () { $("#usernam ...
- 异步请求返回json对象
后台mvc: var result = new { flag = ture, eMail = "949096562@qq.com"}; if (result.flag) { ret ...
- 【Spring学习笔记-MVC-5】利用spring MVC框架,实现ajax异步请求以及json数据的返回
作者:ssslinppp 时间:2015年5月26日 15:32:51 1. 摘要 本文讲解如何利用spring MVC框架,实现ajax异步请求以及json数据的返回. Spring MV ...
- ajax异步请求返回对象
使用ajax异步请求返回一个对象. java code: @RequestMapping({"getAstSingleWheelImg_bbs"+Constant.JSON}) @ ...
- 在使用Ajax请求返回json数据的时候IE浏览器弹出下载保存对话框的解决方法
在使用Ajax请求返回json数据的时候IE浏览器弹出下载保存对话框的解决方法 最近在做一个小东西,使用kindeditor上传图片的时候,自己写了一个上传的方法,按照协议规则通过ajax返回json ...
- AJAX请求,返回json进行页面绑值
AJAX请求,返回json进行页面绑值 后台 controller @RequestMapping(value = "backjson.do",method=RequestMeth ...
- 异步请求取得json数据
一.异步请求 在之前我们请求数据的时候都是整个页面全部刷新了一次,也就是每次请求都会重新请求所有的资源.但是在很多时候不需要页面全部刷新,仅仅是需要页面的局部数据刷新即可,此时需要发送异步请求来实现这 ...
- IOS-网络(HTTP请求、同步请求、异步请求、JSON解析数据)
// // ViewController.m // IOS_0129_HTTP请求 // // Created by ma c on 16/1/29. // Copyright © 2016年 博文科 ...
- Ajax异步请求返回文件流(eg:导出文件时,直接将导出数据用文件流的形式返回客户端供客户下载)
在异步请求中要返回文件流,不能使用JQuery,因为$.ajax,$.post 不支持返回二进制文件流的类型,可以看到下图,dataType只支持xml,json,script,html这几种格式,没 ...
随机推荐
- 求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222。
方法一: var num = ""; var nums = []; var a = Number(prompt());//所要拼接的数字 var b = Number(prompt ...
- Go 变量(var) & 常量(const)
变量 声明变量格式: var var_name var_type 变量在声明时会自动初始化: 数字: 0 string: "" bool: false 引用类型: nil 结构体: ...
- Python:程序练习题(二)
Python:程序练习题(二) 2.1温度转换程序. 代码如下: t=input("请输入带符号的温度值(如:32C):") if t[-1] in ["C", ...
- CentOS下yum方式安装FFmpeg
FFmpeg一个完整的跨平台解决方案,用于记录,转换和流式传输音频和视频. 文档:https://www.ffmpeg.org/documentation.html FFmpeg安装 1.安装Nux ...
- C# params 可变参数使用注意
今天在一个 .NET Core 项目中调用一个自己实现的使用 params 可变参数的方法时触发了 null 引用异常,原以为是方法中没有对参数进行 null 值检查引起的,于是加上 check nu ...
- 一站式解决Mac--socket.gaierror: [Errno 8] nodename nor servname provided, or not known
socket.gaierror: [Errno 8] nodename nor servname provided, or not known 原因:hostname 没有写在/etc/hosts里 ...
- new 关键字 和 newInstance() 方法的 区别
区别1: new是一个关键字,可以说是一个指令: newInstance()是一个方法,Class对象的一个方法. 区别2: new主要作用是在内存中生成一个实例,而这个类可以没有提前加载到内从中: ...
- Windows安装与配置—MongoDB
1,下载安装 打开下载链接:http://dl.mongodb.org/dl/win32/x86_64,选择后缀是2008plus-ssl-3.6.15.zip的版本,32位和64位通用. 2,安装配 ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 6
23.4 API的设计原则和规范 API是服务提供方和使用方之间对接的通道,前面我们设计的一些简单API的例子,基本上比较随意,没有使用任何规范.设想一下,每个平台都可能存在大量的API,如果API ...
- pytest框架优化——清理历史截图图片和allure报告文件
痛点分析: 当我们每次执行完用例的时候,如果出现bug或者是测试脚本出了问题,一般会通过测试报告.异常截图.日志来定位分析,但是我们发现运行次数多了之后,异常截图和测试报告会不停地增多,对我们定位分析 ...