1、在web.xml中配置Shiro的filter

在web系统中,shiro也通过filter进行拦截。filter拦截后将操作权交给spring中配置的filterChain(过虑链儿)

shiro提供很多filter。

<!-- shiro的filter -->
<!-- shiro过虑器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 设置true由servlet容器控制filter的生命周期 -->
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
<!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean-->
<init-param>
<param-name>targetBeanName</param-name>
<param-value>shiroFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

2、在applicationContext-shiro.xml 中配置web.xml中fitler对应spring容器中的bean。##

<!-- web.xml中shiro的filter对应的bean -->
<!-- Shiro 的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
<property name="loginUrl" value="/login.action" />
<!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->
<property name="successUrl" value="/first.action"/>
<!-- 通过unauthorizedUrl指定没有权限操作时跳转页面-->
<property name="unauthorizedUrl" value="/refuse.jsp" />
<!-- 自定义filter配置 -->
<property name="filters">
<map>
<!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中-->
<entry key="authc" value-ref="formAuthenticationFilter" />
</map>
</property> <!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
<property name="filterChainDefinitions">
<value>
</value>
</property>
</bean> <!-- securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm" />
</bean> <!-- realm -->
<bean id="customRealm" class="cn.itcast.ssm.shiro.CustomRealm">
<!-- 将凭证匹配器设置到realm中,realm按照凭证匹配器的要求进行散列 -->
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>

3、配置静态资源的匿名访问

<!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
<property name="filterChainDefinitions">
<value>
<!-- 对静态资源设置匿名访问 -->
/images/** = anon
/js/** = anon
/styles/** = anon
</value>
</property>

4、登录认证的实现

一、原理

使用FormAuthenticationFilter过虑器实现 ,原理如下:



 将用户没有认证时,请求loginurl进行认证,用户身份和用户密码提交数据到loginurl



 FormAuthenticationFilter拦截住取出request中的username和password(两个参数名称是可以配置的)



 FormAuthenticationFilter调用realm传入一个token(username和password)



 realm认证时根据username查询用户信息(在Activeuser中存储,包括 userid、usercode、username、menus)。



 如果查询不到,realm返回null,FormAuthenticationFilter向request域中填充一个参数(记录了异常信息)

二、代码实现

//登陆提交地址,和applicationContext-shiro.xml中配置的loginurl一致
@RequestMapping("login")
public String login(HttpServletRequest request)throws Exception{ //如果登陆失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名
String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
//根据shiro返回的异常类路径判断,抛出指定异常信息
if(exceptionClassName!=null){
if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
//最终会抛给异常处理器
throw new CustomException("账号不存在");
} else if (IncorrectCredentialsException.class.getName().equals(
exceptionClassName)) {
throw new CustomException("用户名/密码错误");
} else if("randomCodeError".equals(exceptionClassName)){
throw new CustomException("验证码错误 ");
}else {
throw new Exception();//最终在异常处理器生成未知错误
}
}
//此方法不处理登陆成功(认证成功),shiro认证成功会自动跳转到上一个请求路径
//登陆失败还到login页面
return "login";
}

三、配置登录的拦截器

<!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
<property name="filterChainDefinitions">
<value>
<!-- 对静态资源设置匿名访问 -->
/images/** = anon
/js/** = anon
/styles/** = anon
<!-- /** = authc 所有url都必须认证通过才可以访问-->
/** = authc
<!-- /** = anon所有url都可以匿名访问 --> </value>

四、退出

不用我们去实现退出,只要去访问一个退出的url(该 url是可以不存在),由LogoutFilter拦截住,清除session。

在applicationContext-shiro.xml配置LogoutFilter

<property name="filterChainDefinitions">
<value>
<!-- 对静态资源设置匿名访问 -->
/images/** = anon
/js/** = anon
/styles/** = anon
<!-- /** = authc 所有url都必须认证通过才可以访问-->
/** = authc
<!-- /** = anon所有url都可以匿名访问 -->
<!-- 请求 logout.action地址,shiro去清除session-->
/logout.action = logout
</value>

五、编写认证的realm

//realm的认证方法,从数据库查询用户信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException { // token是用户输入的用户名和密码
// 第一步从token中取出用户名
String userCode = (String) token.getPrincipal(); // 第二步:根据用户输入的userCode从数据库查询
SysUser sysUser = null;
try {
sysUser = sysService.findSysUserByUserCode(userCode);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} // 如果查询不到返回null
if(sysUser==null){//
return null;
}
// 从数据库查询到密码
String password = sysUser.getPassword(); //盐
String salt = sysUser.getSalt(); // 如果查询到返回认证信息AuthenticationInfo //activeUser就是用户身份信息
ActiveUser activeUser = new ActiveUser(); activeUser.setUserid(sysUser.getId());
activeUser.setUsercode(sysUser.getUsercode());
activeUser.setUsername(sysUser.getUsername());
//.. //根据用户id取出菜单
List<SysPermission> menus = null;
try {
//通过service取出菜单
menus = sysService.findMenuListByUserId(sysUser.getId());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//将用户菜单 设置到activeUser
activeUser.setMenus(menus); //将activeUser设置simpleAuthenticationInfo
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
activeUser, password,ByteSource.Util.bytes(salt), this.getName()); return simpleAuthenticationInfo;
}

六、设置凭证匹配器###

数据库中存储到的md5的散列值,在realm中需要设置数据库中的散列值它使用散列算法 及散列次数,让shiro进行散列对比时和原始数据库中的散列值使用的算法 一致。

 <!-- 凭证匹配器 -->
<bean id="credentialsMatcher"
class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5" />
<property name="hashIterations" value="1" />
</bean>

七、认证通过的Controller

//系统首页
@RequestMapping("/first")
public String first(Model model)throws Exception{ //从shiro的session中取activeUser
Subject subject = SecurityUtils.getSubject();
//取身份信息
ActiveUser activeUser = (ActiveUser) subject.getPrincipal();
//通过model传到页面
model.addAttribute("activeUser", activeUser); return "/first";
}

5、授权的实现

一、授权流程

在applicationContext-shiro.xml中配置url所对应的权限。

授权流程:

1、在applicationContext-shiro.xml中配置filter规则



/items/queryItems.action = perms[item:query]

2、用户在认证通过后,请求/items/queryItems.action

3、被PermissionsAuthorizationFilter拦截,发现需要“item:query”权限

4、PermissionsAuthorizationFilter调用realm中的doGetAuthorizationInfo获取数据库中正确的权限

5、PermissionsAuthorizationFilter对item:query 和从realm中获取权限进行对比,如果“item:query”在realm返回的权限列表中,授权通过。

二、配置授权不通过的拒绝页面

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
<property name="loginUrl" value="/login.action" />
<!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->
<property name="successUrl" value="/first.action"/>
<!-- 通过unauthorizedUrl指定没有权限操作时跳转页面-->
<property name="unauthorizedUrl" value="/refuse.jsp" />

三、此种授权方式存在的问题

1、在applicationContext-shiro.xml中配置过虑器链接,需要将全部的url和权限对应起来进行配置,比较发麻不方便使用。

2、每次授权都需要调用realm查询数据库,对于系统性能有很大影响,可以通过shiro缓存来解决

四、Shiro的过滤器

过滤器简称     对应的java类

 Anon     org.apache.shiro.web.filter.authc.AnonymousFilter

 Authc     org.apache.shiro.web.filter.authc.FormAuthenticationFilter

 authcBasic     org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter

 perms     org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter

 port     org.apache.shiro.web.filter.authz.PortFilter

 rest     org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter

 roles     org.apache.shiro.web.filter.authz.RolesAuthorizationFilter

 ssl     org.apache.shiro.web.filter.authz.SslFilter

 user     org.apache.shiro.web.filter.authc.UserFilter

 logout     org.apache.shiro.web.filter.authc.LogoutFilter

anon:例子/admins/**=anon 没有参数,表示可以匿名使用。

authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,FormAuthenticationFilter是表单认证,没有参数

perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms ["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。

user:例如/admins/user/**=user没有参数表示必须存在用户, 身份认证通过或通过记住我认证通过的可以访问,当登入操作时不做检查

五、授权realm的实现

// 用于授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) { //从 principals获取主身份信息
//将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中身份类型),
ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal(); //根据身份信息获取权限信息
//从数据库获取到权限数据
List<SysPermission> permissionList = null;
try {
permissionList = sysService.findPermissionListByUserId(activeUser.getUserid());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//单独定一个集合对象
List<String> permissions = new ArrayList<String>();
if(permissionList!=null){
for(SysPermission sysPermission:permissionList){
//将数据库中的权限标签 符放入集合
permissions.add(sysPermission.getPercode());
}
} /* List<String> permissions = new ArrayList<String>();
permissions.add("user:create");//用户的创建
permissions.add("item:query");//商品查询权限
permissions.add("item:add");//商品添加权限
permissions.add("item:edit");//商品修改权限**/
//查到权限数据,返回授权信息(要包括 上边的permissions)
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//将上边查询到授权信息填充到simpleAuthorizationInfo对象中
simpleAuthorizationInfo.addStringPermissions(permissions); return simpleAuthorizationInfo;
}

六、开启controller的aop支持

<!-- 开启aop,对类代理 -->
<aop:config proxy-target-class="true"></aop:config>
<!-- 开启shiro注解支持 -->
<bean
class="
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>

七、在controller中添加注解完成授权

//商品信息方法
@RequestMapping("/queryItems")
@RequiresPermissions("item:query")//执行queryItems需要"item:query"权限
public ModelAndView queryItems(HttpServletRequest request) throws Exception { System.out.println(request.getParameter("id")); //调用service查询商品列表
List<ItemsCustom> itemsList = itemsService.findItemsList(null); ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemsList", itemsList);
// 指定逻辑视图名
modelAndView.setViewName("itemsList"); return modelAndView;
}

八、jsp页面通过标签授权

Jsp页面添加:

<%@ tagliburi="http://shiro.apache.org/tags" prefix="shiro" %>

标签名称     标签条件(均是显示标签内容)

shiro:authenticated 登录之后

shiro:notAuthenticated 不在登录状态时

shiro:guest 用户在没有RememberMe时

shiro:user 用户在RememberMe时

<shiro:hasAnyRoles name="abc,123" > 在有abc或者123角色时

<shiro:hasRole name="abc"> 拥有角色abc

<shiro:lacksRole name="abc"> 没有角色abc

<shiro:hasPermission name="abc"> 拥有权限资源abc

<shiro:lacksPermission name="abc"> 没有abc权限资源

shiro:principal 显示用户身份名称

<shiro:principal property="username"/> 显示用户身份中的属性值

jsp页面实例:

<td>
<!-- 有item:update权限才显示修改链接,没有该 权限不显示,相当 于if(hasPermission(item:update)) -->
<shiro:hasPermission name="item:update">
<a href="${pageContext.request.contextPath }/items/editItems.action?id=${item.id}">修改</a>
</shiro:hasPermission>
</td>

6、配置session管理器

和shiro整合后,使用shiro的session管理,shiro提供sessionDao操作 会话数据。

配置sessionManager

<!-- securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm" />
<!-- 注入session管理器 -->
<property name="sessionManager" ref="sessionManager" />
</bean>
<!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- session的失效时长,单位毫秒 -->
<property name="globalSessionTimeout" value="600000"/>
<!-- 删除失效的session -->
<property name="deleteInvalidSessions" value="true"/>
</bean>

7、shiro缓存

一、缓存流程

shiro中提供了对认证信息和授权信息的缓存。shiro默认是关闭认证信息缓存的,对于授权信息的缓存shiro默认开启的。主要研究授权信息缓存,因为授权的数据量大。

用户认证通过。

该 用户第一次授权:调用realm查询数据库

该 用户第二次授权:不调用realm查询数据库,直接从缓存中取出授权信息(权限标识符)。

二、配置缓存管理器

使用ehcache进行缓存管理。

<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
</bean>
!-- securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm" />
<!-- 注入缓存管理器 -->
<property name="cacheManager" ref="cacheManager"/>
<!-- 注入session管理器 -->
<property name="sessionManager" ref="sessionManager" />
</bean>

三、编写ehcache的配置文件

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!--diskStore:缓存数据持久化的目录 地址 -->
<diskStore path="F:\develop\ehcache" />
<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>

四、缓存清空

如果用户正常退出,缓存自动清空。

如果用户非正常退出,缓存自动清空。

如果修改了用户的权限,而用户不退出系统,修改的权限无法立即生效。

需要手动进行编程实现:

在权限修改后调用realm的clearCache方法清除缓存。

下边的代码正常开发时要放在service中调用。

在service中,权限修改后调用realm的方法。

//清除缓存
public void clearCached() {
PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
super.clearCache(principals);
}

编写controller

//注入realm
@Autowired
private CustomRealm customRealm; @RequestMapping("/clearShiroCache")
public String clearShiroCache(){ //清除缓存,将来正常开发要在service调用customRealm.clearCached()
customRealm.clearCached(); return "success";
}

8、验证码的实现

一、验证码的生成

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.Random"%>
<%@ page import="java.io.OutputStream"%>
<%@ page import="java.awt.Color"%>
<%@ page import="java.awt.Font"%>
<%@ page import="java.awt.Graphics"%>
<%@ page import="java.awt.image.BufferedImage"%>
<%@ page import="javax.imageio.ImageIO"%>
<%
int width = 60;
int height = 32;
//create the image
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
// set the background color
g.setColor(new Color(0xDCDCDC));
g.fillRect(0, 0, width, height);
// draw the border
g.setColor(Color.black);
g.drawRect(0, 0, width - 1, height - 1);
// create a random instance to generate the codes
Random rdm = new Random();
String hash1 = Integer.toHexString(rdm.nextInt());
System.out.print(hash1);
// make some confusion
for (int i = 0; i < 50; i++) {
int x = rdm.nextInt(width);
int y = rdm.nextInt(height);
g.drawOval(x, y, 0, 0);
}
// generate a random code
String capstr = hash1.substring(0, 4);
//将生成的验证码存入session
session.setAttribute("validateCode", capstr);
g.setColor(new Color(0, 100, 0));
g.setFont(new Font("Candara", Font.BOLD, 24));
g.drawString(capstr, 8, 24);
g.dispose();
//输出图片
response.setContentType("image/jpeg");
out.clear();
out = pageContext.pushBody();
OutputStream strm = response.getOutputStream();
ImageIO.write(image, "jpeg", strm);
strm.close();
%>

二、在登录页面加入验证码

<TR>
<TD>验证码:</TD>
<TD><input id="randomcode" name="randomcode" size="8" /> <img
id="randomcode_img" src="${baseurl}validatecode.jsp" alt=""
width="56" height="20" align='absMiddle' /> <a
href=javascript:randomcode_refresh()>刷新</a></TD>
</TR>

三、自定义FormAuthenticationFilter过滤器

public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {

	//原FormAuthenticationFilter的认证方法
@Override
protected boolean onAccessDenied(ServletRequest request,
ServletResponse response) throws Exception {
//在这里进行验证码的校验 //从session获取正确验证码
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpSession session =httpServletRequest.getSession();
//取出session的验证码(正确的验证码)
String validateCode = (String) session.getAttribute("validateCode"); //取出页面的验证码
//输入的验证和session中的验证进行对比
String randomcode = httpServletRequest.getParameter("randomcode");
if(randomcode!=null && validateCode!=null && !randomcode.equals(validateCode)){
//如果校验失败,将验证码错误失败信息,通过shiroLoginFailure设置到request中
httpServletRequest.setAttribute("shiroLoginFailure", "randomCodeError");
//拒绝访问,不再校验账号和密码
return true;
}
return super.onAccessDenied(request, response);
} }

四、配置自定义FormAuthenticationFilter过滤器

<!-- Shiro 的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
<property name="loginUrl" value="/login.action" />
<!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->
<property name="successUrl" value="/first.action"/>
<!-- 通过unauthorizedUrl指定没有权限操作时跳转页面-->
<property name="unauthorizedUrl" value="/refuse.jsp" />
<!-- 自定义filter配置 -->
<property name="filters">
<map>
<!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中-->
<entry key="authc" value-ref="formAuthenticationFilter" />
</map>
</property> <!-- 自定义form认证过虑器 -->
<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
<bean id="formAuthenticationFilter"
class="cn.itcast.ssm.shiro.CustomFormAuthenticationFilter ">
<!-- 表单中账号的input名称 -->
<property name="usernameParam" value="username" />
<!-- 表单中密码的input名称 -->
<property name="passwordParam" value="password" />
</bean>

五、在login.action对验证错误 进行解析

public String login(HttpServletRequest request)throws Exception{

		//如果登陆失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名
String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
//根据shiro返回的异常类路径判断,抛出指定异常信息
if(exceptionClassName!=null){
if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
//最终会抛给异常处理器
throw new CustomException("账号不存在");
} else if (IncorrectCredentialsException.class.getName().equals(
exceptionClassName)) {
throw new CustomException("用户名/密码错误");
} else if("randomCodeError".equals(exceptionClassName)){
throw new CustomException("验证码错误 ");
}else {
throw new Exception();//最终在异常处理器生成未知错误
}
}
//此方法不处理登陆成功(认证成功),shiro认证成功会自动跳转到上一个请求路径
//登陆失败还到login页面
return "login";
}

六、在filter配置匿名访问验证码jsp

<!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
<property name="filterChainDefinitions">
<value>
<!-- 对静态资源设置匿名访问 -->
/images/** = anon
/js/** = anon
/styles/** = anon
<!-- 验证码,可匿名访问 -->
/validatecode.jsp = anon

9、记住我实现

一、 用户身份实现java.io.Serializable接口

二、配置rememeberMeManager

<!-- rememberMeManager管理器,写cookie,取出cookie生成用户信息 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cookie" ref="rememberMeCookie" />
</bean>
<!-- 记住我cookie -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<!-- rememberMe是cookie的名字 -->
<constructor-arg value="rememberMe" />
<!-- 记住我cookie生效时间30天 -->
<property name="maxAge" value="2592000" />
</bean> <!-- securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm" />
<!-- 注入缓存管理器 -->
<property name="cacheManager" ref="cacheManager"/>
<!-- 注入session管理器 -->
<property name="sessionManager" ref="sessionManager" />
<!-- 记住我 -->
<property name="rememberMeManager" ref="rememberMeManager"/> </bean>

三、在登录页面加入记住我选项

<tr>
<TD></TD>
<td><input type="checkbox" name="rememberMe" />自动登陆</td>
</tr>

四、配置rememberMe的input名称

<!-- 自定义form认证过虑器 -->
<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
<bean id="formAuthenticationFilter"
class="cn.itcast.ssm.shiro.CustomFormAuthenticationFilter ">
<!-- 表单中账号的input名称 -->
<property name="usernameParam" value="username" />
<!-- 表单中密码的input名称 -->
<property name="passwordParam" value="password" />
<!-- 记住我input的名称 -->
<property name="rememberMeParam" value="rememberMe"/>
</bean>

五、使用UserFilter

如果设置记住我,下次访问某些url时可以不用登陆。将记住我即可访问的地址配置让UserFilter拦截。

	<!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
<property name="filterChainDefinitions">
<value>
<!-- 对静态资源设置匿名访问 -->
/images/** = anon
/js/** = anon
/styles/** = anon
<!-- 验证码,可匿名访问 -->
/validatecode.jsp = anon <!-- 请求 logout.action地址,shiro去清除session-->
/logout.action = logout
<!--商品查询需要商品查询权限 ,取消url拦截配置,使用注解授权方式 -->
<!-- /items/queryItems.action = perms[item:query]
/items/editItems.action = perms[item:edit] -->
<!-- 配置记住我或认证通过可以访问的地址 -->
/index.jsp = user
/first.action = user
/welcome.jsp = user
<!-- /** = authc 所有url都必须认证通过才可以访问-->
/** = authc
<!-- /** = anon所有url都可以匿名访问 --> </value>
</property>

最新文章

  1. 为简单而努力:Android封装类详解
  2. UVa 11889 Benefit(数论)
  3. JDBC连接池
  4. Web前端面试题集锦
  5. 深入了解Ant构建工具 命令
  6. MyBatis环境搭建
  7. C#多态;父类引用指向子类对象;new和override的区别;new、abstract、virtual、override,sealed关键字区别和使用代码示例;c#类的初始化顺序
  8. 慎用ReentrantLock
  9. FFMPEG图片转视频
  10. 1001 A + B Problem
  11. SpringMVC(三)-- 视图和视图解析器、数据格式化标签、数据类型转换、SpringMVC处理JSON数据、文件上传
  12. Ubuntu下安装Texmaker的问题与解决方案
  13. cadence学习二-----&gt;Allegro基本概念
  14. js正则表达式 URL格式匹配详解
  15. 在JavaEE中使用Mybatis框架
  16. 【JS】正则向前查找和向后查找
  17. 软件工程---gjb438b 质量规范体系
  18. mybatis学习系列四--mybatis generator逆向工程
  19. oracle(一)复习起航
  20. android 打开系统相机,

热门文章

  1. Android-ContentProvider简单的增删改查
  2. C# 二维码生成——QRCode
  3. HBase介绍 (1)---数据模型
  4. 【Oracle】安装注意事项
  5. linux和windows之间的文件压缩和解压缩以及^R的问题
  6. Python自动发送HTML测试报告
  7. Gsteramer 环境配置
  8. 清除bean中所有非基本数据类型的属性值
  9. React第二篇:组件的生命周期
  10. [Alpha]Scrum Meeting#2