原因:当我们使用Shiro发送AJAX请求的时候,会自动跳转页面(而AJAX不能跳转页面,添砖会出很多错误)
因为是shiro自己的原因,所以我们需要使用我们自己定义的
在shiro中使用这个类PermissionsAuthorizationFilter来过滤请求所以覆写
AJAX特点
普通请求
AJAX
所以我们可以通过七种不同来判断是否为AJAX请求
写一个类继承PermissionsAuthorizationFilter
package cn.jiedada.aisell.web.shiro; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.StringUtils; import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter; import org.apache.shiro.web.util.WebUtils; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * 写一个自己的Shiro来判断出我们需要的东西处理Ajax权限 */ public class AisellPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException { Subject subject = this.getSubject(request, response); //判断用户是否登陆 if (subject.getPrincipal() == null) { this.saveRequestAndRedirectToLogin(request, response); } else { //只用通过HttpServletRequest才能获得请求头中的数据才能判断 HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse=(HttpServletResponse)response; //查看是否是AjAX请求 String xRequested = httpRequest.getHeader("X-Requested-With"); if(xRequested!=null&&"XMLHttpRequest".equals(xRequested)){ //传入前需要在请求头中传入响应,让他知道我们返回的数据是AJAX请求 httpResponse.setContentType("text/json; charset=UTF-8"); //带回AJAX请求,把数据作为流传回去这里需要传出标准的json数据格式 httpResponse.getWriter().print( "{\"success\":false,\"msg\":\"没有权限\"}"); }else { String unauthorizedUrl = this.getUnauthorizedUrl(); if (StringUtils.hasText(unauthorizedUrl)) { WebUtils.issueRedirect(request, response, unauthorizedUrl); } else { WebUtils.toHttp(response).sendError(401); } } } return false; } }
把application-shiro.xml中默认的配置设置为我们自己的配置
<?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-3.0.xsd"> <!-- DefaultSecurityManager securityManager = new DefaultSecurityManager();--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!--引入到securityManager的realm--> <property name="realm" ref="myRealm"/> </bean> <!--配置我自己的realm--> <bean id="myRealm" class="cn.jiedada.aisell.web.shiro.MyRealm"> <!--name无关紧要--> <property name="name" value="myRealm"/> <!----> <property name="credentialsMatcher"> <!-- 设置密码解析器 HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("MD5"); hashedCredentialsMatcher.setHashIterations(10); --> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="MD5"/> <property name="hashIterations" value="10"/> </bean> </property> </bean> <!--下放请求到当前页面--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!--当我们没登陆的是否跳到当前页面--> <property name="loginUrl" value="/login"/> <!--登陆成功调到该页面--> <property name="successUrl" value="/s/index.jsp"/> <!--有权限的,如果没有则跳转到该页面--> <property name="unauthorizedUrl" value="/s/unauthorized.jsp"/> <!--/s/login = anon放行 /s/permission.jsp = perms[user:index]需要user:index权限才能访问 /** = authc --> <!-- <property name="filterChainDefinitions"> <value> /s/login = anon /login = anon /s/permission.jsp = perms[user:index] /** = authc </value> </property>--> <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property> <!--配置一个可以不适用默认连接Shiro的 通过key区分是我们的shiro还是自带的 map.put(p.getUrl(),"perms["+p.getSn()+"]");这样是自带的 而 map.put(p.getUrl(),"aisellPers["+p.getSn()+"]");就变成了我们这个的权限 --> <property name="filters"> <map> <entry key="aisellPers" value-ref="aisellPermissionsAuthorizationFilter"></entry> </map> </property> </bean> <bean id="aisellPermissionsAuthorizationFilter" class="cn.jiedada.aisell.web.shiro.AisellPermissionsAuthorizationFilter"></bean> <bean id="filterChainDefinitionMap" factory-bean="shiroFilterMapFactory" factory-method="createMap" /> <!--配置返回shiro权限拦截的bean--> <bean id="shiroFilterMapFactory" class="cn.jiedada.aisell.web.shiro.ShiroFilterMapFactory"/> </beans>
其实就是这一句
<property name="filters">
<map>
<entry key="aisellPers" value-ref="aisellPermissionsAuthorizationFilter"></entry>
</map>
</property>
</bean>
<bean id="aisellPermissionsAuthorizationFilter" class="cn.jiedada.aisell.web.shiro.AisellPermissionsAuthorizationFilter"></bean>
然后需要把我们shrio中默认的值改为aisellPers这个为我们上面的key值
List<Permission> permissions = permissionService.findAll(); permissions.forEach(p->{ map.put(p.getUrl(),"aisellPers["+p.getSn()+"]"); });