1.Shiro概述
Apache Shiro 是一个强大易用的 Java 安全框架
Apache Shiro 是一个强大易用的 Java 安全框架,提供了认证、授权、加密和会话管理等功能,对于任何一个应用程序,Shiro 都可以提供全面的安全管理服务。并且相对于其他安全框架,Shiro 要简单的多。
简介
Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境。Shiro 可以帮助我们完成:认证、授权、加密、会话管理、与 Web 集成、缓存等。这不就是我们想要的嘛,而且 Shiro 的 API 也是非常简单;其基本功能点如下图所示:
组件 | 描述 |
---|---|
Authentication | 身份认证 / 登录,验证用户是不是拥有相应的身份 |
Authorization | 授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限 |
SessionManager | 会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的。 |
整合框架中自定义Shiro组件全部位于com.brillilab.ssmdemo.common.shiro包中
子包 | 描述 |
---|---|
com.brillilab.ssmdemo.common.shiro.cache | 自定义缓存组件,用于进行认证信息、权限信息和会话信息的缓存操作 |
com.brillilab.ssmdemo.common.shiro.filter | 自定义权限过滤器 |
com.brillilab.ssmdemo.common.shiro.listenter | 自定义会话监听器 |
com.brillilab.ssmdemo.common.shiro.realms | 自定义Realms |
com.brillilab.ssmdemo.common.shiro.session | 自定义Session缓存管理组件,用于进行Sesssion缓存的操作,主要组件为SessionDAO和SessionRepository |
com.brillilab.ssmdemo.common.shiro.token | 自定义Token,使用不同的自定义Token可以实现不数据结构的Token |
com.brillilab.ssmdemo.common.shiro.utils | 相关工具包 |
3.配置文件
(1)applicationContext-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"
-
xmlns:p=
"http://www.springframework.org/schema/p"
-
xmlns:context=
"http://www.springframework.org/schema/context"
-
xmlns:util=
"http://www.springframework.org/schema/util"
-
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
-
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
-
http://www.springframework.org/schema/context
-
http://www.springframework.org/schema/context/spring-context-3.1.xsd
-
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
-
-
<!-- (一)rememberMe管理器 -->
-
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
-
<!-- rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)-->
-
<property name="cipherKey"
-
value=
"#{T(org.apache.shiro.codec.Base64).decode('3AvVhmFLUs0KTA3Kprsdag==')}"/>
-
<property name="cookie" ref="rememberMeCookie"/>
-
</bean>
-
<!-- 用户信息记住我功能的相关配置 -->
-
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
-
<constructor-arg value="v_v-re-baidu"/>
-
<property name="httpOnly" value="true"/>
-
<!-- 配置存储rememberMe Cookie的domain为 一级域名
-
<property name="domain" value=".itboy.net"/>
-
-->
-
<property name="maxAge" value="2592000"/>
<!-- 30天时间,记住我30天 -->
-
</bean>
-
-
-
<!-- (二)SecurityManager -->
-
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
-
<property name="realm" ref="userRealm"/>
-
<property name="sessionManager" ref="sessionManager"/>
-
<property name="rememberMeManager" ref="rememberMeManager"/>
-
<property name="cacheManager" ref="customShiroCacheManager"/>
-
</bean>
-
<!-- ShiroCacheManager -->
<!-- 用于缓存AuthenticationInfo -->
-
<bean id="customShiroCacheManager" class="com.brillilab.ssmdemo.common.shiro.cache.impl.CustomShiroCacheManager">
-
<property name="shiroCacheManager" ref="jedisShiroCacheManager"/>
-
</bean>
-
<!-- shiro 缓存实现,对ShiroCacheManager,我是采用redis的实现 -->
-
<bean id="jedisShiroCacheManager" class="com.brillilab.ssmdemo.common.shiro.cache.impl.JedisShiroCacheManager">
-
<property name="jedisManager" ref="jedisManager"/>
-
</bean>
-
-
<!-- 授权 认证 -->
-
<bean id="userRealm" class="com.brillilab.ssmdemo.common.shiro.realms.UserRealm" >
-
<property name="cacheManager" ref="customShiroCacheManager"/>
-
<property name="cachingEnabled" value="false"/>
-
<property name="authenticationCachingEnabled" value="true"/>
-
<property name="authenticationCacheName" value="authenticationCache"/>
-
<property name="authorizationCachingEnabled" value="true"/>
-
<property name="authorizationCacheName" value="authorizationCache"/>
-
</bean>
-
-
-
<!-- (三)SessionManager -->
-
<!-- DefaultWebSessionManager -->
-
<bean id="customShiroSessionDAO" class="com.brillilab.ssmdemo.common.shiro.session.CustomShiroSessionDAO">
-
<property name="shiroSessionRepository" ref="jedisShiroSessionRepository"/>
-
<property name="sessionIdGenerator" ref="sessionIdGenerator"/>
-
</bean>
-
-
<!-- SessionDAO -->
-
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
-
<!-- 相隔多久检查一次session的有效性 -->
-
<property name="sessionValidationInterval" value="180000"/>
-
<!-- session 有效时间为半小时 (毫秒单位)-->
-
<property name="globalSessionTimeout" value="180000"/>
-
<property name="sessionDAO" ref="customShiroSessionDAO"/>
-
<!-- session 监听,可以多个。 -->
-
<property name="sessionListeners">
-
<list>
-
<ref bean="customSessionListener"/>
-
</list>
-
</property>
-
<!-- 不需要注入sessionValidationScheduler 属性-->
-
<!--<property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>-->
-
<!-- 是否开启 检测,默认开启 -->
-
<property name="sessionValidationSchedulerEnabled" value="true"/>
-
<!-- 是否删除无效的,默认也是开启 -->
-
<property name="deleteInvalidSessions" value="true"/>
-
<!-- 会话Cookie模板 -->
-
<property name="sessionIdCookie" ref="sessionIdCookie"/>
-
</bean>
-
<!-- 会话Session ID生成器 -->
-
<bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
-
-
<!-- session 创建、删除、查询 -->
-
<bean id="jedisShiroSessionRepository" class="com.brillilab.ssmdemo.common.shiro.session.JedisShiroSessionRepository" >
-
<property name="jedisManager" ref="jedisManager"/>
-
</bean>
-
<!-- 会话Cookie模板 -->
-
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
-
<!--cookie的name,我故意取名叫xxxxbaidu -->
-
<constructor-arg value="v_v-s-baidu"/>
-
<property name="httpOnly" value="true"/>
-
<!--cookie的有效时间 -->
-
<property name="maxAge" value="180000"/>
-
<!-- 配置存储Session Cookie的domain为 一级域名
-
<property name="domain" value=".itboy.net"/>
-
-->
-
</bean>
-
<!-- custom shiro session listener -->
-
<bean id="customSessionListener" class="com.brillilab.ssmdemo.common.shiro.listenter.CustomSessionListener">
-
<property name="shiroSessionRepository" ref="jedisShiroSessionRepository"/>
-
</bean>
-
-
-
<!-- (四)JedisManager redis缓存管理器(DAO) -->
-
<bean id="jedisManager" class="com.brillilab.ssmdemo.common.shiro.cache.JedisManager">
-
<property name="jedisPool" ref="jedisPool"/>
-
</bean>
-
-
<!-- (五)shiro权限过滤器 -->
-
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
-
<property name="securityManager" ref="securityManager" />
-
<property name="loginUrl" value="/login" />
-
<property name="successUrl" value="/index" />
-
<property name="unauthorizedUrl" value="/login" />
-
<!-- 过滤器映射 -->
-
<property name="filterChainDefinitions" >
-
<value>
-
/common/** = anon
-
/login = anon
-
/index = anon
-
/user/insert = login,permission
-
/user/delete = login,permission
-
/logout = anon
-
</value>
-
</property>
-
<property name="filters">
-
<util:map>
-
<entry key="login" value-ref="login"/>
-
<entry key="role" value-ref="role"/>
-
<entry key="permission" value-ref="permission"/>
-
<entry key="logout" value-ref="logout"/>
-
</util:map>
-
</property>
-
</bean>
-
<!-- 自定义权限过滤器 -->
-
<bean id="login" class="com.brillilab.ssmdemo.common.shiro.filter.LoginFilter"/>
-
<bean id="role" class="com.brillilab.ssmdemo.common.shiro.filter.RoleFilter"/>
-
<bean id="permission" class="com.brillilab.ssmdemo.common.shiro.filter.PermissionFilter"/>
-
<bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter">
-
<property name="redirectUrl" value="/index"/>
-
</bean>
-
-
<!-- (六)Shiro生命周期处理器-->
-
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
-
</beans>
(2)web.xml的编写
-
<!-- ShiroFilter -->
-
<filter>
-
<filter-name>shiroFilter
</filter-name>
-
<filter-class>org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
-
</filter>
-
<filter-mapping>
-
<filter-name>shiroFilter
</filter-name>
-
<url-pattern>/*
</url-pattern>
-
</filter-mapping>
*注意:shiro的自定义组件全部在com.brillilab.ssmdemo.shiro包中
4.Shiro基础操作的使用示例
以下所有操作均在web情景中进行
(1)登录校验
-
@RequestMapping(value =
"/login",method = RequestMethod.POST)
-
public
String login(User user,
Boolean rememberme, HttpServletRequest request, HttpServletResponse response){
-
try {
-
//1.获取认证对象
-
Subject subject = SecurityUtils.getSubject();
-
-
-
//2.实例化Token对象
-
String sessionId=request.getRequestedSessionId();
-
String username=user.getUsername();
-
String password=user.getPassword();
-
-
UsernamePasswordToken token=
new UsernamePasswordToken(username,password,rememberme);
-
-
//3.进行登录认证
-
subject.login(token);
-
-
}
catch (Exception e){
-
return
"error/loginerror";
-
}
-
-
return
"redirect:/index";
-
}
(2)登出操作
-
@RequestMapping("/logout")
-
public String logout(HttpServletRequest request, HttpServletResponse response){
-
-
Subject subject = SecurityUtils.getSubject();
-
subject.logout();
-
-
return
"redirect:/index";
-
}
(3)自定义Realm
-
public
class UserRealm extends AuthorizingRealm {
-
-
@Autowired
-
UserService userService;
-
@Autowired
-
RoleService roleService;
-
@Autowired
-
PermissionService permissionService;
-
-
/**
-
* 授权信息,用于进行权限认证
-
*/
-
@Override
-
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
-
//(1)获得签名, 可做进一步查询
-
User token= (User) principalCollection.getPrimaryPrincipal();
-
User user=userService.login(token);
-
//(2)创建SimpleAuthenticationInfo对象
-
SimpleAuthorizationInfo info=
new SimpleAuthorizationInfo();
-
//(3)查询角色、权限信息
-
Set<String> roles = roleService.findRolesByUser(user);
-
info.setRoles(roles);
-
-
Set<String> permissions = permissionService.findPermissionsByUser(user);
-
info.addStringPermissions(permissions);
-
return info;
-
}
-
-
/**
-
* 认证信息,主要针对用户登录,
-
*/
-
@Override
-
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
-
//(1)获取登录的token
-
UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
-
//(2)获取username和password,调用登录
-
String username=token.getUsername();
-
String password=
new String(token.getPassword());
-
-
User user=
new User();
-
user.setUsername(username);
-
user.setPassword(password);
-
-
User login = userService.login(user);
-
-
//(3)登录失败
-
if (
null==login){
-
throw
new AccountException(
"账号或密码不正确!");
-
}
-
if (login.getStatus()==
0){
-
throw
new DisabledAccountException(
"帐号已经禁止登录!");
-
}
-
-
//(4)登录成功
-
login.setUpdatetime(
new Date());
-
userService.updateUser(login);
-
-
return
new SimpleAuthenticationInfo(login,login.getPassword(),login.getUsername());
-
}
-
}
(4)权限校验
-
Subject subject = SecurityUtils.getSubject();
-
-
List<
String> roles = Arrays.asList(
new
String[]{
"admin",
"super"});
-
subject.hasAllRoles(roles);
-
subject.hasRole(
"admin");
(5)JSP页面内容授权
-
在JSP页面引入Shiro标签ku
<pre class="has" style="margin-left:0px;" name="code" "hljs.copyCode(event)"><code style="margin-left:0px;" class="hljs swift"><%@ taglib <span class="hljs-keyword">prefix</span>=<span class="hljs-string">"shiro"</span> uri=<span class="hljs-string">"http://shiro.apache.org/tags"</span> %>
<shiro:guest>标签中的类容在游客访问时显示
-
<pre class="has" style="margin-left:0px;" name="code" "hljs.copyCode(event)"><code style="margin-left:0px;" class="hljs vbscript-html"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="xml"><span class="hljs-comment"><!-- shiro标签测试 --></span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-tag"><<span class="hljs-name">shiro:guest</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-tag"><<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-item"</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-link"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/login"</span>></span>Login<span class="hljs-tag"></<span class="hljs-name">a</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-tag"></<span class="hljs-name">li</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"></<span class="hljs-attr">shiro:guest</span>></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"></div></div></li></ol></code><div class="hljs-button {2}" data-title="复制"></div></pre> </li> <li style="margin-left:0px;"> <p style="margin-left:0px;"><shiro:hasRole name="1">标签中的内容在用户登录情况下,角色包含name属性值时显示</p> <pre class="has" style="margin-left:0px;" name="code" "hljs.copyCode(event)"><code style="margin-left:0px;" class="hljs vbscript-html"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="xml"><span class="hljs-tag"><<span class="hljs-name">shiro:hasRole</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"1"</span>></span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-tag"><<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-item"</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-link"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>></span>管理员<span class="hljs-tag"></<span class="hljs-name">a</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-tag"></<span class="hljs-name">li</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"></<span class="hljs-attr">shiro:hasRole</span>></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"></div></div></li></ol></code><div class="hljs-button {2}" data-title="复制"></div></pre> </li> <li style="margin-left:0px;"> <p style="margin-left:0px;"><shiro:hasPermission name="/user/insert">标签中的类容在用户登录情况下,权限包含name属性值时显示</p> <pre class="has" style="margin-left:0px;" name="code" "hljs.copyCode(event)"><code style="margin-left:0px;" class="hljs vbscript-html"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="xml"><span class="hljs-tag"><<span class="hljs-name">shiro:hasPermission</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"/user/insert"</span>></span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-tag"><<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-item"</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-link"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>></span>能够添加用户<span class="hljs-tag"></<span class="hljs-name">a</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-tag"></<span class="hljs-name">li</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"></<span class="hljs-attr">shiro:hasPermission</span>></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"></div></div></li></ol></code><div class="hljs-button {2}" data-title="复制"></div></pre> </li>
5.Shiro自定义权限过滤器
(1)自定义拦截器的配置
-
<!-- (五)shiro权限过滤器 -->
-
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
-
<property name="securityManager" ref="securityManager" />
-
<property name="loginUrl" value="/login" />
-
<property name="successUrl" value="/index" />
-
<property name="unauthorizedUrl" value="/login" />
-
<!-- 过滤器映射 -->
-
<property name="filterChainDefinitions" >
-
<value>
-
/common/** = anon
-
/login = anon
-
/index = anon
-
/user/insert = login,permission
-
/user/delete = login,permission
-
</value>
-
</property>
-
<property name="filters">
-
<util:map>
-
<entry key="login" value-ref="login"> </entry>
-
<entry key="role" value-ref="role"> </entry>
-
</util:map>
-
</property>
-
</bean>
-
<!-- 自定义拦截器 -->
-
<bean id="login" class="com.brillilab.ssmdemo.common.shiro.filter.LoginFilter"/>
-
<bean id="role" class="com.brillilab.ssmdemo.common.shiro.filter.RoleFilter"/>
-
<bean id="permission" class="com.brillilab.ssmdemo.common.shiro.filter.PermissionFilter"/>
(2)登录过滤器
1.LoginFilter
-
public class LoginFilter extends AccessControlFilter {
-
/**
-
* 写如何能通过该拦截器的逻辑
-
*/
-
@Override
-
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object o) throws Exception {
-
//(1)获取认证信息
-
User token = (User)SecurityUtils.getSubject().getPrincipal();
-
//(2)登录请求直接放行
-
if( null != token || isLoginRequest(request, response)){
-
return true;
-
}
-
-
//(3)非登录请求,重定向到登录页面
-
ResultVo result = ResultVoUtil.failed( "当前用户没有登录!");
-
WebUtil.jsonOut(response,result);
-
-
return false;
-
}
-
-
/**
-
* isAccessAllowed返回值为fales时经过该方法
-
*/
-
@Override
-
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
-
//保存Request和Response 到登录后的链接
-
saveRequestAndRedirectToLogin(request, response);
-
return false;
-
}
-
}
(3)权限过滤器
2.RoleFilter
-
public class RoleFilter extends AccessControlFilter {
-
/**
-
* 写如何能通过该拦截器的逻辑
-
*/
-
@Override
-
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object value) throws Exception {
-
//(1)获取认证实体
-
Subject subject = getSubject(request, response);
-
//(2)进行角色校验(角色为"1"能通过)
-
if (subject.hasAllRoles(Arrays.asList( "1"))){
-
return true;
-
}
-
//(3)未通过角色校验重定向回登录页面
-
((HttpServletResponse)response).sendRedirect(request.getServletContext().getContextPath()+ "/login");
-
return false;
-
}
-
-
/**
-
* isAccessAllowed返回值为fales时经过该方法
-
*/
-
@Override
-
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
-
//(3)未通过角色校验重定向回登录页面
-
//((HttpServletResponse)response).sendRedirect(request.getServletContext().getContextPath()+"/login");
-
Subject subject = getSubject(request, response);
-
if (subject.getPrincipal()== null){
-
//未登录重定向登录页面
-
saveRequest(request);
-
WebUtils.issueRedirect(request,response,((HttpServletRequest)request).getContextPath()+ "/login");
-
} else {
-
//已登录重定向未授权错误页面
-
WebUtils.issueRedirect(request,response,((HttpServletRequest)request).getContextPath()+ "/error/unauthorizerror");
-
}
-
return false;
-
}
-
}
3.PermissionFilter
-
public class PermissionFilter extends AccessControlFilter {
-
-
/**
-
* 写如何能通过该拦截器的逻辑
-
*/
-
@Override
-
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object o) throws Exception {
-
//(1)获取认证实体
-
Subject subject = getSubject(request,response);
-
//(2)进行权限校验
-
//①获取请求url
-
HttpServletRequest httpRequest=(HttpServletRequest)request;
-
String url = httpRequest.getRequestURI();
-
String contextPath = httpRequest.getContextPath();
-
if (url!= null && url.startsWith(contextPath)){
-
url = url.replaceFirst(contextPath, "");
-
}
-
//②权限校验
-
if (subject.isPermitted(url)){
-
return true;
-
}
-
return false;
-
}
-
-
/**
-
* isAccessAllowed返回值为fales时经过该方法
-
*/
-
@Override
-
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
-
//(3)未通过权限校验的逻辑
-
Subject subject = getSubject(request, response);
-
if (subject.getPrincipal()== null){
-
//未登录重定向登录页面
-
saveRequest(request);
-
WebUtils.issueRedirect(request,response,((HttpServletRequest)request).getContextPath()+ "/login");
-
} else {
-
//已登录重定向未授权错误页面
-
WebUtil.jsonOut(response,ResultVoUtil.failed( "用户未被授权该操作"));
-
}
-
return false;
-
}
-
}
-