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这几种格式,没 ...
随机推荐
- 整理几个经常在H5移动端开发遇到的东西。
本篇主要是我个人的学习分享. 1.弹出数字键盘 <!-- 有“#” “*” 符号输入 --> <input type="tel"> <!-- 纯数字 ...
- Least Common Multiple (HDU - 1019) 【简单数论】【LCM】【欧几里得辗转相除法】
Least Common Multiple (HDU - 1019) [简单数论][LCM][欧几里得辗转相除法] 标签: 入门讲座题解 数论 题目描述 The least common multip ...
- jenkins传统模式发布istio应用
一.发布金丝雀版本 Pre Setps cd /var/lib/jenkins/workspace/istio-service-user-canary/istio-service-user # 旧版本 ...
- JS模仿腾讯图片新闻
仿照腾讯图片新闻的幻灯,功能并不完全一样.最开始打算做这个的时候,突然觉得好像做不来.想想如果一步一步,一个功能一个功能的做应该能搞定. 我做这个例子的思路是这样的: 先把需要的html和css代码写 ...
- HTML连载46-浮动元素字围现象、浮动练习
一.浮动元素的字围现象 div{ float:left; width:100px; height:100px; background-color: red; border:1px solid blac ...
- kvm与xen虚拟化的比较(转)
Linux虚拟化技术的用户目前有两种免费的开源管理程序可以选择:Xen和KVM. 作为较早出现的虚拟化技术,Xen是“第一类”运行在裸机上的虚拟化管理程序(Hypervisor),也是当前相当一部分商 ...
- linux的vi编辑器常用用法一览
vi 命令用于编辑文本文件,语法: vi 文件名 vi 是一个比较强大的编辑工具,类似于windows下的notepad,但是功能要强大的多.vi分为三种模式,分别是“一般模式”,“编辑模式”,“命令 ...
- .Net ADO拼接带参数的SQL语句
首先是在DAL数据访问层中的代码://数据更新的方法public static int shuxing_update(s_passnature model) { string sql = " ...
- Redis for OPS 07:Redis 补充说明
写在前面的话 redis 的各种架构搭建暂时就到这里,本文主要用于补充说明 Redis 的一些概念以及配置文件的相关信息. 常用词汇 缓存穿透: 类似热点数据存储 Redis 一样,对于非热点数据存储 ...
- python基础(24):面向对象三大特性一(继承)
1. 继承 1.1 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类. python中类的继承分为:单继承和多继 ...