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: * @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
相关推荐
杜鲁门 2020-11-05
luckyxl0 2020-08-16
Dullonjiang 2020-08-09
xclxcl 2020-08-03
zmzmmf 2020-08-03
MicroBoy 2020-08-02
ganjing 2020-08-02
likesyour 2020-08-01
zmzmmf 2020-07-09
MicroBoy 2020-07-05
zzhao 2020-06-26
子云 2020-06-18
visionzheng 2020-06-07
neweastsun 2020-06-04
ErixHao 2020-06-03
GDreams0 2020-06-01
ganjing 2020-05-29
zmzmmf 2020-05-28
nullcy 2020-05-26