自定义realm;

/**
* 认证和授权
*/
@Component
public class UserRealm extends AuthorizingRealm { @Autowired
private UserService userService;
@Autowired
private AuthService authService; /**
* 授权(验证权限时调用)
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
User user = (User)principals.getPrimaryPrincipal();
Integer userId = user.getUserId();
List<String> permsList = null; //系统管理员,拥有最高权限
if(userId == ){
List<Auth> menuList = authService.queryList(new HashMap<String, Object>());
permsList = new ArrayList<String>(menuList.size());
for(Auth menu : menuList){
permsList.add(menu.getPerms());
}
}else{
permsList = userService.queryAllPerms(userId);
}
//用户权限列表
Set<String> permsSet = new HashSet<String>();
for(String perms : permsList){
if(StringUtils.isBlank(perms)){
continue;
}
permsSet.addAll(Arrays.asList(perms.trim().split(",")));
} SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(permsSet);
return info;
} /**
* 认证(登录时调用)
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken)authcToken; //查询用户信息
User user = userService.queryByUserName(token.getUsername());
//账号不存在
if(user == null) {
throw new UnknownAccountException("账号不存在");
}
SimpleAuthenticationInfo info =null;
info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()),getName());
return info;
} @Override
public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
HashedCredentialsMatcher shaCredentialsMatcher = new CustomUserMatche();
shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.hashAlgorithmName);
shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
super.setCredentialsMatcher(shaCredentialsMatcher);
}
}

1、UserRealm父类AuthorizingRealm将获取Subject相关信息分成两步:获取身份验证信息(doGetAuthenticationInfo)及授权信息(doGetAuthorizationInfo);

2、doGetAuthenticationInfo获取身份验证相关信息:首先根据传入的用户名获取User信息;然后如果user为空,那么抛出没找到帐号异常UnknownAccountException;如果user找到但锁定了抛出锁定异常LockedAccountException;最后生成AuthenticationInfo信息,交给间接父类AuthenticatingRealm使用CredentialsMatcher进行判断密码是否匹配,如果不匹配将抛出密码错误异常IncorrectCredentialsException;另外如果密码重试此处太多将抛出超出重试次数异常ExcessiveAttemptsException;在组装SimpleAuthenticationInfo信息时,需要传入:身份信息(用户名)、凭据(密文密码)、盐(username+salt),CredentialsMatcher使用盐加密传入的明文密码和此处的密文密码进行匹配。

3、doGetAuthorizationInfo获取授权信息:PrincipalCollection是一个身份集合,因为我们现在就一个Realm,所以直接调用getPrimaryPrincipal得到之前传入的用户名即可;然后根据用户名调用UserService接口获取角色及权限信息。

shiro系列三、定义Realm的更多相关文章

  1. Apache Shiro系列三,概述 —— 10分钟入门

     一.介绍 看完这个10分钟入门之后,你就知道如何在你的应用程序中引入和使用Shiro.以后你再在自己的应用程序中使用Shiro,也应该可以在10分钟内搞定. 二.概述 关于Shiro的废话就不多说了 ...

  2. shiro系列三、ssm框架整合shiro实现权限控制

    shiro权限框架是一个非常优秀的框架,前面的几篇文章对shiro进行了非常详细的介绍和原理分析,那么接下来让我们开始在web项目中使用它(javase也能用shiro): 一.数据库表结构设计 二. ...

  3. Apache Shiro系列之五,概述 —— 配置

    Shiro设计的初衷就是可以运行于任何环境:无论是简单的命令行应用程序还是复杂的企业集群应用.由于运行环境的多样性,所以有多种配置机制可用于配置,本节我们将介绍Shiro内核支持的这几种配置机制.   ...

  4. Apache Shiro系列四,概述 —— Shiro的架构

    Shiro的设计目标就是让应用程序的安全管理更简单.更直观.     软件系统一般是基于用户故事来做设计.也就是我们会基于一个客户如何与这个软件系统交互来设计用户界面和服务接口.比如,你可能会说:“如 ...

  5. shiro实战系列(七)之Realm

    Realm 是一个能够访问应用程序特定的安全数据(如用户.角色及权限)的组件.Realm 将应用程序特定的数据转 换成一种 Shiro 能够理解的格式,这样 Shiro 能够提供一个单一的易理解的 S ...

  6. WCF编程系列(三)地址与绑定

    WCF编程系列(三)地址与绑定   地址     地址指定了接收消息的位置,WCF中地址以统一资源标识符(URI)的形式指定.URI由通讯协议和位置路径两部分组成,如示例一中的: http://loc ...

  7. Shiro 系列 - 基本知识

    和 Spring Security 项目一样, Apache Shiro 也是一个被广泛使用安全框架, 它们都能完成认证.授权.会话管理等. 简单对比一下 Apache Shiro 和 Spring ...

  8. 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gulp专家

    系列目录 前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gul ...

  9. SQL Server 2008空间数据应用系列三:SQL Server 2008空间数据类型

    原文:SQL Server 2008空间数据应用系列三:SQL Server 2008空间数据类型 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server ...

随机推荐

  1. IEnumerable和IQueryable口的区别

    IQueryable: 动态表达式树拼接查询语句,把拼接后查询语句进行执行:Execute触发,延迟加载IEnumerable:对内存中的数据,动态拼接查询语句,进行查询:ToList触发,延迟加载: ...

  2. JAVA 基础编程练习题42 【程序 42 求数字】

    42 [程序 42 求数字] 题目:809*??=800*??+9*??+1 其中??代表的两位数,8*??的结果为两位数,9*??的结果为 3 位数.求??代表的两位数,及 809*??后的结 果. ...

  3. windows和Linux下定时启动或关闭服务

    http://blog.csdn.net/clare504/article/details/17410643 1.Windows下的定时启动程序可以采用系统的计划和任务,定时启动服务可以在计划任务中添 ...

  4. antd二级联动异步加载

    /** * Created by Admin on 2016/9/19. * 批量导入 */ import React, {Component, PropTypes} from "react ...

  5. 深度学习中的Attention机制

    1.深度学习的seq2seq模型 从rnn结构说起 根据输出和输入序列不同数量rnn可以有多种不同的结构,不同结构自然就有不同的引用场合.如下图, one to one 结构,仅仅只是简单的给一个输入 ...

  6. 神经网络手写数字识别numpy实现

    本文摘自Michael Nielsen的Neural Network and Deep Learning,该书的github网址为:https://github.com/mnielsen/neural ...

  7. Hadoop学习笔记之二 文件操作

    HDFS分布式文件系统:优点:支持超大文件存储.流式访问.一次写入多次读取.缺点:不适应大量小文件.不适应低时延的数据访问.不适应多用户访问任意修改文件. 1.hadoop用于大数据处理,在数据量较小 ...

  8. 【miscellaneous】如何利用硬盘号和CPU序列号为软件加密

    原文:http://www.jiamisoft.com/blog/index.php/3469-yingpanhaocpuruanjianjiami.html 计算机软件是一种特殊的产品,为了防止软件 ...

  9. 微信小程序的calc不生效处理

    大致文字初略的记录描述一下问题:外层是relative相对定位,内部一个view 需要绝对定位bottom的值为128rpx,同时还要兼容适配苹果x的底部,所以值是这样设置的: bottom: cal ...

  10. CDH6.2的spark访问oss

    CDH6配置oss后:spark的配置 /opt/cloudera/parcels/CDH-6.2.0-1.cdh6.2.0.p0.967373/jars/opt/cloudera/parcels/C ...