一、认证

1、添加凭证匹配器

添加凭证匹配器实现md5加密校验。

修改applicationContext-shiro.xml:

    <!-- realm -->
<bean id="customRealm" class="com.lhx.ssm.shiro.CustomRealm">
<!-- 将凭证匹配器设置到realm中,realm按照凭证匹配器的要求进行散列 -->
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean> <!-- 凭证匹配器 -->
<bean id="credentialsMatcher"
class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5"/>
<property name="hashIterations" value="1"/>
</bean>

2、修改realm认证方法

修改realm代码从数据库中查询用户身份信息,将sysService注入realm。

public class CustomRealm extends AuthorizingRealm {

    //注入service
@Autowired
private SysService sysService; // 设置realm的名称
@Override
public void setName(String name) {
super.setName("customRealm");
}
// 支持什么类型的token
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
} // 用于认证
//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;
}
// ……授权下一个
}

二、授权

1.修改realm授权方法

修改realm代码从数据库中查询权限信息,将sysService注入realm

public class CustomRealm extends AuthorizingRealm {

    //注入service
@Autowired
private SysService sysService; // 设置realm的名称
@Override
public void setName(String name) {
super.setName("customRealm");
}
// 支持什么类型的token
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
} // 用于认证
//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;
} // 用于授权
@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;
}
}

2、对controller开启aop

在springmvc.xml中配置shiro注解支持,可在controller方法中使用shiro注解配置权限:

    <!-- 开启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>

3、权限注解控制

商品查询controller方法添加权限(item:query):

    // 查询商品列表
@RequestMapping("/queryItem")
@RequiresPermissions("item:query")
public ModelAndView queryItem() throws Exception {

上边代码@RequiresPermissions("item:query")表示必须拥有“item:query”权限方可执行。

同理,商品修改controller方法添加权限(item:update):

    @RequestMapping(value = "/editItem")
@RequiresPermissions("item:update")
public String editItem(@RequestParam(value = "id", required = true) Integer id, Model model) throws Exception

商品提交

    // 商品修改提交
@RequestMapping("/editItemSubmit")
@RequiresPermissions("item:update")
public String editItemSubmit(@ModelAttribute("item") Items items,BindingResult result,MultipartFile pictureFile,Model model,HttpServletRequest request)
throws Exception

4、jsp标签控制

4.1、标签简介

a、Jsp页面添加:

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

b、详细

标签名称

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

<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"/>     显示用户身份中的属性值

4.2、jsp页面添加标签

如果有商品修改权限页面显示“修改”链接。

<shiro:hasPermission name="item:update">
<a href="${pageContext.request.contextPath }/item/editItem.action?id=${item.id}">修改</a>
</shiro:hasPermission>

三、session管理

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

    <!-- 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>

008-shiro与spring web项目整合【二】认证、授权、session管理的更多相关文章

  1. 007-shiro与spring web项目整合【一】基础搭建

    一.需求 将原来基于url的工程改成使用shiro实现 二.代码 https://github.com/bjlhx15/shiro.git 中的permission_shiro 三.去除原项目拦截器 ...

  2. 010-shiro与spring web项目整合【四】缓存Ehcache

    一.Ehcache shiro每次授权都会通过realm获取权限信息,为了提高访问速度需要添加缓存,第一次从realm中读取权限数据,之后不再读取,这里Shiro和Ehcache整合. 1.添加Ehc ...

  3. 009-shiro与spring web项目整合【三】验证码、记住我

    一.验证码 1.自定义FormAuthenticationFilter 需要在验证账号和名称之前校验验证码 /** * * <p>Title: CustomFormAuthenticati ...

  4. (转)shiro权限框架详解06-shiro与web项目整合(下)

    http://blog.csdn.net/facekbook/article/details/54962975 shiro和web项目整合,实现类似真实项目的应用 web项目中认证 web项目中授权 ...

  5. (转) shiro权限框架详解06-shiro与web项目整合(上)

    http://blog.csdn.net/facekbook/article/details/54947730 shiro和web项目整合,实现类似真实项目的应用 本文中使用的项目架构是springM ...

  6. spring web项目中整合netty, akka

    spring web项目中整合netty, akka 本身的web项目仍然使用tomcat/jetty8080端口, 在org.springframework.beans.factory.Initia ...

  7. Spring与Web项目整合的原理

    引言: 在刚开始我们接触IOC时,我们加载并启用SpringIOC是通过如下代码手动加载 applicationContext.xml 文件,new出context对象,完成Bean的创建和属性的注入 ...

  8. Spring Boot 项目学习 (二) MySql + MyBatis 注解 + 分页控件 配置

    0 引言 本文主要在Spring Boot 基础项目的基础上,添加 Mysql .MyBatis(注解方式)与 分页控件 的配置,用于协助完成数据库操作. 1 创建数据表 这个过程就暂时省略了. 2 ...

  9. 实战突击: Java Web项目整合开发(PDF)

    实战突击:  Java  Web项目整合开发(PDF)

随机推荐

  1. JavaScript学习日志(2)

    javascript数据类型: 字符串string.数字number.未定义Undefined.空Null.布尔Boolean.数组Array.对象Object.javascript对象: 对象由花括 ...

  2. 字符串操作:int 转 string

    strstream ss; string ch; ss<<i; ss>>ch;

  3. asp.net写日志权限问题

    asp.net网站程序写不了日志,都是这个原因. 程序池的身份标识,设为内置的网络服务即可.

  4. Jquery学习笔记(4)--checkbox全选反选

    可能有浏览器兼容性,注意html里的checked是一个属性,存在就默认选中. <!DOCTYPE html> <html lang="en"> <h ...

  5. 1.2.2 Loaders - 加载器

    Loaders从Android 3.0引入,它使得在activity或是fragment里进行异步数据加载变得非常简单.Loaders有如下的特性: 它在每个 Activity  和 Fragment ...

  6. The Definitive Guide To Django 2 学习笔记(二) 第二个View 动态内容

    “Hello World”只是简单的展现了Django 基本的工作机制,但它不是动态的网页.第二个View我们将创建一个动态的网页,该页面上将展现当前的时间和日期. 该View需要做两件事,第一,计算 ...

  7. 利用:header匹配所有标题做目录

    1.问题背景 查找到h1-h6,并遍历它们,打印出内容 2.实现源码 <!DOCTYPE html> <html> <head> <meta charset= ...

  8. Linux CentOS 修改内核引导顺序

    CentOS 7.0 系统更改内核启动顺序 可以 uname -a查下当前的 由于 CentOS 7 使用 grub2 作为引导程序,所以和 CentOS 6 有所不同,并不是修改 /etc/grub ...

  9. jQuery实现浮动层跟随页面滚动效果

      helloweba.com Author:月光光 Time:2010-11-29 09:02 Tag: jquery  滚动 在本文中,我将介绍一个可以跟随页面滚动的层效果,当用户滚动鼠标滚轮或者 ...

  10. DESEncrypt.cs

    POJ上做做ACM的题 语言的学习基础,100个经典的算法C语言的学习要从基础开始,这里是100个经典的算法-1C语言的学习要从基础开始,这里是100个经典的算法 题目:古典问题:有一对兔子,从出生后 ...