准备
数据库准备
Permission:权限表
Role:角色表
Role_permission:权限和角色的关系表
User:用户表
User_role:用户和角色和关系表
create database ssm_shiro;
user ssm_shiro;
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (
`perid` INT(11) NOT NULL AUTO_INCREMENT,
`pername` VARCHAR(255) DEFAULT NULL,
`percode` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`perid`)
) ENGINE=INNODB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
INSERT INTO `permission` VALUES ('1', '用户查询', 'user:query');
INSERT INTO `permission` VALUES ('2', '用户添加', 'user:add');
INSERT INTO `permission` VALUES ('3', '用户修改', 'user:update');
INSERT INTO `permission` VALUES ('4', '用户删除', 'user:delete');
INSERT INTO `permission` VALUES ('5', '导出用户', 'user:export');
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`roleid` INT(11) NOT NULL AUTO_INCREMENT,
`rolename` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`roleid`)
) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `role` VALUES ('1', '超级管理员');
INSERT INTO `role` VALUES ('2', 'CEO');
INSERT INTO `role` VALUES ('3', '保安');
DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission` (
`perid` INT(255) DEFAULT NULL,
`roleid` INT(11) DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `role_permission` VALUES ('1', '1');
INSERT INTO `role_permission` VALUES ('2', '1');
INSERT INTO `role_permission` VALUES ('3', '1');
INSERT INTO `role_permission` VALUES ('4', '1');
INSERT INTO `role_permission` VALUES ('1', '2');
INSERT INTO `role_permission` VALUES ('2', '2');
INSERT INTO `role_permission` VALUES ('3', '2');
INSERT INTO `role_permission` VALUES ('1', '3');
INSERT INTO `role_permission` VALUES ('5', '3');
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`userid` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) DEFAULT NULL,
`userpwd` VARCHAR(255) DEFAULT NULL,
`sex` VARCHAR(255) DEFAULT NULL,
`address` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`userid`)
) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `user` VALUES ('1', 'zhangsan', '639ffb0cbcca39d4fff8348844b1974e', '男', '武汉');
INSERT INTO `user` VALUES ('2', 'lisi', '0d303fa8e2e2ca98555f23a731a58dd9', '女', '北京');
INSERT INTO `user` VALUES ('3', 'wangwu', '473c41db9af5cc0d90e7adfd2b6d9180', '女', '成都');
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
`userid` INT(11) DEFAULT NULL,
`roleid` INT(11) DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user_role` VALUES ('1', '1');
INSERT INTO `user_role` VALUES ('2', '2');
INSERT INTO `user_role` VALUES ('3', '3');
数据结构
张三:user:query、user:add、user:update、user:delete
李四:user:query 、user:add、user:update
王五:user:query、user:export
密码说明:使用登录名和地址作为盐、散列2次。
搭建SSM环境
略,可以参考我的gitee的SSM整合:https://gitee.com/coydone/ssm_crud/tree/master
SSM整合博客:https://www.coydone.com/?p=125
【SSM整合】博客园:https://www.cnblogs.com/coydone/p/13742678.html
使用MBG自动生成mapper代码。
整合Shiro
pom文件导入shiro依赖
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
编写数据库实体
使用MBG工具自动生成,略。可以在实体上实现序列化接口。
public class User implements Serializable {}
编写mapper
mapper层接口和mapper.xml文件由MBG工具自动生成,略。
修改mapper层、添加MBG没有提供的方法。
- PermissionMapper
List<Permission> queryPermissionsByUserId(Integer userid);
<!-- 根据用户ID查询用户拥有的权限 -->
<select id="queryPermissionsByUserId" resultMap="BaseResultMap">
select distinct t1.* from permission t1 inner join role_permission t2 inner join user_role t3
on(t1.perid=t2.perid and t2.roleid=t3.roleid)
where t3.userid=#{userid}
</select>
- RoleMapper
List<Role> queryRolesByUserId(Integer userid);
<!-- 根据用户ID查询用户拥有的角色 -->
<select id="queryRolesByUserId" resultMap="BaseResultMap">
select t1.* from role t1 inner join user_role t2 on(t1.roleid=t2.roleid)
where t2.userid=#{userid}
</select>
- UserMapper
User queryUserByUserName(String username);
<!-- 根据用户名查询用户 -->
<select id="queryUserByUserName" resultMap="BaseResultMap">
select * from user where username=#{username}
</select>
编写service层
- PermissionService
public interface PermissionService {
/**
* 根据用户ID查询用户拥有的权限
* @param userid
* @return
*/
List<String> queryPermissionsByUserId(Integer userid);
}
package com.coydone.service.impl;
@Service
public class PermissionServiceImpl implements PermissionService {
@Autowired
private PermissionMapper permissionMapper;
@Override
public List<String> queryPermissionsByUserId(Integer userid) {
List<Permission> permissionList=permissionMapper.queryPermissionsByUserId(userid);
List<String> permissions=new ArrayList<>();
for (Permission permission : permissionList) {
permissions.add(permission.getPercode());
}
return permissions;
}
}
- RoleService
public interface RoleService {
/**
* 根据用户ID查询用户拥有的角色
* @param userid
* @return
*/
List<String> queryRolesByUserId(Integer userid);
}
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleMapper roleMapper;
@Override
public List<String> queryRolesByUserId(Integer userid) {
List<Role> roleList=roleMapper.queryRolesByUserId(userid);
List<String> roles=new ArrayList<String>();
for (Role role : roleList) {
roles.add(role.getRolename());
}
return roles;
}
}
- UserService
public interface UserService {
/**
* 根据用户名查询用户对象
* @param username
* @return
*/
User queryUserByUserName(String username);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User queryUserByUserName(String username) {
User user=userMapper.queryUserByUserName(username);
return user;
}
}
我们需要将用户的信息、角色、权限存储到session中,于是我们定义一个ActiveUser封装我们需要的这些信息。
package com.coydone.utils;
import com.coydone.entity.User;
import java.util.List;
public class ActiveUser {
private User user;
private List<String> roles;
private List<String> permissions;
//省略getter()、setter()、有参、无参构造
}
编写Controller
@Controller
@RequestMapping("user")
public class UserController {
@RequestMapping("loadAllUser")
public String loadAllUser() {
return "list";
}
}
@Controller
@RequestMapping("login")
public class LoginController {
/**
* 跳转到登陆页面
*/
@RequestMapping("toLogin")
public String toLogin() {
return "login";
}
/**
* 完成登陆的方法
*/
@RequestMapping("login")
public String login(String username, String password, HttpSession session) {
// 1,得到主体
Subject subject = SecurityUtils.getSubject();
// 2,封装用户名和密码
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
ActiveUser activerUser = (ActiveUser) subject.getPrincipal();
session.setAttribute("user", activerUser.getUser());
return "redirect:/user/loadAllUser";
} catch (AuthenticationException e) {
System.out.println("用户名或密码不正确");
}
return "redirect:index.jsp";
}
}
自定义Realm
创建UserRealm
2、创建UserRealm
package com.coydone.realm;
import com.coydone.entity.User;
import com.coydone.service.PermissionService;
import com.coydone.service.RoleService;
import com.coydone.service.UserService;
import com.coydone.utils.ActiveUser;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.List;
public class UserRealm extends AuthorizingRealm {
@Override
public String getName() {
return this.getClass().getSimpleName();
}
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Autowired
private PermissionService permssionService;
/**
* 完成认证的方法
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = token.getPrincipal().toString();
Object credentials = token.getCredentials();// 用户登陆时传过来的
System.out.println(Arrays.toString((char[]) credentials));
// 根据用户名查询用户是否存在
User user = this.userService.queryUserByUserName(username);
// 返回null说明用户不存在
if (null != user) {
// 根据用户名去查询用户拥有哪些角色
List<String> roles = roleService.queryRolesByUserId(user.getUserid());
// 根据用户名查询用户拥有哪些权限
List<String> permissions = this.permssionService.queryPermissionsByUserId(user.getUserid());
ActiveUser activeUser = new ActiveUser(user, roles, permissions);
/**
* 参数1 用户身份 参数2 用户在数据库里面存放的密码 参数3 当前类名
*/
// SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(activeUser,
// user.getPassword(), this.getName());
/**
* 参数1:传到doGetAuthorizationInfo里面getPrimaryPrincipal()的对象或者subject.getPrincipal()
* 参数2:hashedCredentials 加密之后的密码 参数3:credentialsSalt 盐
*/
ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUsername()+user.getAddress());
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(activeUser, user.getUserpwd(), credentialsSalt,
this.getName());
return info;
}
return null;
}
/**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 根据用户名去查询用户拥有哪些角色
List<String> roles = activeUser.getRoles();
if (null != roles && roles.size() > 0) {
// 添加角色
info.addRoles(roles);
}
// 根据用户名查询用户拥有哪些权限
List<String> permissions = activeUser.getPermissions();
// 添加权限
if (null != permissions && permissions.size() > 0) {
// 添加角色
info.addStringPermissions(permissions);
}
return info;
}
}
修改配置
4、在Spring的配置文件中配置Shiro
<!-- ============== 配置shiro 开始============= -->
<!-- 声明凭证匹配器 -->
<bean id="credentialsMatcher"
class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 注入加密方式 -->
<property name="hashAlgorithmName" value="md5"></property>
<!-- 注入散列次数 -->
<property name="hashIterations" value="2"></property>
</bean>
<!-- 声明userRealm -->
<bean id="userRealm" class="com.coydone.realm.UserRealm">
<!-- 注入凭证匹配器 -->
<property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>
<!-- 声明安全管理器 -->
<bean id="securityManager"
class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 注入realm -->
<property name="realm" ref="userRealm"></property>
</bean>
<!-- 配置shrio的过滤器链 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入安全管理器 -->
<property name="securityManager" ref="securityManager"></property>
<!-- 注入如果没认证 跳转的页面 -->
<property name="loginUrl" value="/index.jsp"></property>
<!-- 未授权的跳转页 -->
<property name="unauthorizedUrl" value="login/toUnauthorized"></property>
<property name="filterChainDefinitions">
<value>
<!-- 放行系统首页 -->
/index.jsp*=anon
<!-- 放行跳转到登陆页面的地 -->
/login/toLogin*=anon
<!-- 放行登陆的方法 -->
/login/login*=anon
<!-- 其它的页面都要认证 -->
/**=authc
</value>
</property>
</bean>
<!-- ============== 配置shiro 结束============= -->
修改web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 配置shiro的代理过滤器 开始 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<!-- 这里的shrioFilter必须和spring配置shiro里面的 过滤器ID一致 -->
<param-name>targetBeanName</param-name>
<param-value>shiroFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<servlet-name>dispatcherServlet</servlet-name>
</filter-mapping>
<!-- 配置shiro的代理过滤器 结束 -->
<!-- 配置编码过滤器开始 -->
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 注入属性 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<!-- <url-pattern>/*</url-pattern> -->
<servlet-name>dispatcherServlet</servlet-name>
</filter-mapping>
<!-- 配置编码过滤器结束 -->
<!--配置全局参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--监听全局配置参数-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置springmvc的核心拦截器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
编写页面
- index.jsp
<body>
<jsp:forward page="login/toLogin"></jsp:forward>
</body>
- login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1 align="center">用户登陆</h1>
<hr>
<form action="${pageContext.request.contextPath}/login/login" method="post">
<table align="center" width="50%" border="1" cellpadding="2" cellspacing="5">
<tr>
<td align="right">用户名:</td>
<td>
<input type="text" name="username">
</td>
</tr>
<tr>
<td align="right">密码:</td>
<td>
<input type="password" name="password">
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="登陆">
</td>
</tr>
</table>
</form>
</body>
</html>
- list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<shiro:hasPermission name="user:query">
<h2>
<a href="">查询用户</a>
</h2>
</shiro:hasPermission>
<shiro:hasPermission name="user:add">
<h2>
<a href="">添加用户</a>
</h2>
</shiro:hasPermission>
<shiro:hasPermission name="user:update">
<h2>
<a href="">修改用户</a>
</h2>
</shiro:hasPermission>
<shiro:hasPermission name="user:delete">
<h2>
<a href="">删除用户</a>
</h2>
</shiro:hasPermission>
<shiro:hasPermission name="user:export">
<h2>
<a href="">导出用户</a>
</h2>
</shiro:hasPermission>
</body>
</html>
实现记住我功能
1、在登陆页面添加记住我的复选框
<tr>
<td colspan="2">
<input type="checkbox" name="rememberMe" value="1" > 记住我
</td>
</tr>
2、修改LoginController
3、修改Spring中对Shiro的配置。
包括配置cookie、配置rememberMe、并注入到安全管理器中,然后修改需要认证的页面。
<!-- ============== 配置shiro 开始============= -->
<!-- cookie的配置 -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe"></constructor-arg>
<!-- 只有http请求时才能使用cookie -->
<property name="httpOnly" value="true"></property>
<!-- 设置cookie的存活时间 7天 单位为秒 -->
<property name="maxAge" value="604800"></property>
</bean>
<!-- 声明记住我的管理对象 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cookie" ref="rememberMeCookie"></property>
</bean>
<!-- 声明凭证匹配器 -->
<bean id="credentialsMatcher"
class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 注入加密方式 -->
<property name="hashAlgorithmName" value="md5"></property>
<!-- 注入散列次数 -->
<property name="hashIterations" value="2"></property>
</bean>
<!-- 声明userRealm -->
<bean id="userRealm" class="com.coydone.realm.UserRealm">
<!-- 注入凭证匹配器 -->
<property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>
<!-- 声明安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 注入realm -->
<property name="realm" ref="userRealm"></property>
<!-- 注入rememberMeManager -->
<property name="rememberMeManager" ref="rememberMeManager"></property>
</bean>
<!-- 配置shrio的过滤器链 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入安全管理器 -->
<property name="securityManager" ref="securityManager"></property>
<!-- 注入如果没认证 跳转的页面 -->
<property name="loginUrl" value="/index.jsp"></property>
<!-- 未授权的跳转页 -->
<property name="unauthorizedUrl" value="login/toUnauthorized"></property>
<property name="filterChainDefinitions">
<value>
<!-- 放行系统首页 -->
/index.jsp*=anon
<!-- 放行跳转到登陆页面的地 -->
/login/toLogin*=anon
<!-- 放行登陆的方法 -->
/login/login*=anon
<!-- 其它的页面都要认证 -->
/**=user
/*=authc
/*/*=authc
</value>
</property>
</bean>
<!-- ============== 配置shiro 结束============= -->
4、在shiro里面使用的类实现序列化接口,包括User、Permission、Role、ActiveUser。
public class Permission implements Serializable {}
public class Role implements Serializable {}
public class User implements Serializable{}
public class ActiveUser implements Serializable {}
5、解决session无法获取的问题
此时shiro官方提供的rememberMe方法无法满足我们的业务需求,我们需要重写它提供的方法。
- 创建RememberMeFilter
package com.coydone.filter;
import com.coydone.utils.ActiveUser;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class RememberMeFilter extends FormAuthenticationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
Subject subject=getSubject(request, response);
Session session=subject.getSession();
//记住我的功能isAuthenticated肯定为false 而isRemembered肯定为true
if(!subject.isAuthenticated()&&subject.isRemembered()&&session.getAttribute("user")==null) {
//说明是记住我的功能
ActiveUser activeUser=(ActiveUser) subject.getPrincipal();
if(null!=activeUser) {
session.setAttribute("user", activeUser.getUser());
}
}
return true;
}
}
- 在Spring的配置文件中注入我们自定义的RememberMeFilter。
<!-- 声明自定义RememberMeFilter -->
<bean id="RememberMeFilter" class="com.coydone.filter.RememberMeFilter"></bean>
<!-- 配置shrio的过滤器链 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入自定义过滤器 -->
<property name="filters">
<map>
<entry key="rememberMe" value-ref="RememberMeFilter"></entry>
</map>
</property>
</bean>
<property name="filterChainDefinitions">
<value>
<!-- 其它的页面都要认证 -->
/**=rememberMe,user
/*=authc
/*/*=authc
</value>
</property>
6、测试
在list.jsp中添加${user.username}
,登录选择记住我,关闭浏览器,直接访问list页面,发现会显示用户名。
前后端分离配置
1、修改控制器中改为向页面输出json
@RestController
@RequestMapping("user")
public class UserController {
@RequestMapping("query")
@RequiresPermissions("user:query")
public Map<String,Object> query(){
Map<String,Object> map=new HashMap<>();
map.put("msg", "query");
return map;
}
}
2、创建GlobalExceptionHanderAdvise全局异常监控
//全局的异常监控
//@ControllerAdvice 这个注解是监视Controller里面是否有异常发生,如果发生就跳转页面
@RestControllerAdvice
public class GlobalExceptionHanderAdvise {
//未授权
@ExceptionHandler(value= {UnauthorizedException.class})
public Object unauthorized() {
Map<String,Object> map=new HashMap<>();
map.put("code", -1);
map.put("msg", "未授权,请联系管理员");
return map;
}
}
3、修改springmvc.xml开启shiro注解
<!-- 扫描异常监视器 -->
<context:component-scan base-package="com.coydone.exception"></context:component-scan>
<!-- 启动Shrio的注解 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor" />
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
4、解决未登陆不使用重定向使用JSON的问题
创建ShiroLoginFilter
public class ShiroLoginFilter extends FormAuthenticationFilter {
/**
* 在访问controller前判断是否登录,返回json,不进行重定向。
* @param request
* @param response
* @return true-继续往下执行,false-该filter过滤器已经处理,不继续执行其他过滤器
* @throws Exception
*/
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//if (isAjax(request)) {
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json");
Map<String,Object> resultData = new HashMap<>();
resultData.put("code", -1);
resultData.put("msg", "登录认证失效,请重新登录!"); httpServletResponse.getWriter().write(JSONObject.toJSON(resultData).toString());
/* } else {
// saveRequestAndRedirectToLogin(request, response);
//非ajax请求重定向为登录页面
httpServletResponse.sendRedirect("/login");
}*/
return false;
}
private boolean isAjax(ServletRequest request) {
String header = ((HttpServletRequest) request).getHeader("X-Requested-With");
if ("XMLHttpRequest".equalsIgnoreCase(header)) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}
}
5、修改Spring中对shiro的配置【覆盖authc的过滤器】
<property name="filters">
<map>
<entry key="authc">
<bean class="com.coydone.filter.ShiroLoginFilter"></bean>
</entry>
</map>
</property>
<property name="filterChainDefinitions">
<value>
<!-- /** = authc 所有url都必须认证通过才可以访问 -->
/index.jsp*=anon
/login/toLogin*=anon
/login/login*=anon
<!-- 如果用户访问user/logout就使用Shiro注销session -->
/login/logout = logout
<!-- /** = anon所有url都不可以匿名访问 -->
<!-- /** = authc -->
<!-- /*/* = authc -->
<!-- /** = authc所有url都不可以匿名访问 必须放到最后面 -->
/** = authc
</value>
</property>