多realm配置

public class MyRealm1 implements Realm {

    public String getName() {
return "myrealm1";
}
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken; //仅支持UsernamePasswordToken类型的Token
}
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String)token.getPrincipal(); //得到用户名
String password = new String((char[])token.getCredentials()); //得到密码
if(!"zhang".equals(username)) {
throw new UnknownAccountException(); //如果用户名错误
}
if(!"123".equals(password)) {
throw new IncorrectCredentialsException(); //如果密码错误
}
//如果身份认证验证成功,返回一个AuthenticationInfo实现;
return new SimpleAuthenticationInfo(username, password, getName());
}
} public class MyRealm2 implements Realm { public String getName() {
return "myrealm2";
} public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken; //仅支持UsernamePasswordToken类型的Token
} public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String)token.getPrincipal(); //得到用户名
String password = new String((char[])token.getCredentials()); //得到密码
if(!"wang".equals(username)) {
throw new UnknownAccountException(); //如果用户名错误
}
if(!"123".equals(password)) {
throw new IncorrectCredentialsException(); //如果密码错误
}
//如果身份认证验证成功,返回一个AuthenticationInfo实现;
return new SimpleAuthenticationInfo(username, password, getName());
}
} [main]
#声明一个realm
myRealm1=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm1
myRealm2=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm2
#指定securityManager的realms实现
securityManager.realms=$myRealm1,$myRealm2

securityManege会按照realm指定顺序进行身份验证,没有指定(securityManager.realms=myRealm1,myRealm2)也可以,那就会按照申明顺序进行使用。当显示指定realm后,其他没有被指定realm会被忽略,如:securityManage.realms=$myRealm1,那么myRealm2就不会被设置进realms。

@Test
public void testCustomMultiRealm() {
//1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
Factory<org.apache.shiro.mgt.SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro-multi-realm.ini"); //2、得到SecurityManager实例 并绑定给SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager); //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("wang", "123"); try {
//4、登录,即身份验证
subject.login(token);
} catch (AuthenticationException e) {
//5、身份验证失败
e.printStackTrace();
} Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录 //6、退出
subject.logout();
}

jdbcRealm使用

[main]
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/shiro
dataSource.username=root
dataSource.password=root
jdbcRealm.dataSource=$dataSource
securityManager.realms=$jdbcRealm

测试代码同上

问题记录:

当使用身份凭证登录后,再获取token信息时,如何设置token中放置的内容?

查看JdbcRealm类源码,可以看到doGetAuthenticationInfo(AuthenticationToken token)方法返回一个SimpleAuthenticationInfo info= new SimpleAuthenticationInfo(username, password.toCharArray(), this.getName());故而token中只放了username。

下面这个自定义realm类,在内部查询数据库,综合了自定义realm与jdbcRealm。

public class SampleRealm extends AuthorizingRealm {

    @Autowired
UUserService userService;
@Autowired
PermissionService permissionService;
@Autowired
RoleService roleService; public SampleRealm() {
super();
} /**
* 认证信息,主要针对用户登录,
*/
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException { ShiroToken token = (ShiroToken) authcToken;
UUser user = userService.login(token.getUsername(), token.getPswd());
if (null == user) {
throw new AccountException("帐号或密码不正确!");
/**
* 如果用户的status为禁用。那么就抛出<code>DisabledAccountException</code>
*/
} else if (UUser._0.equals(user.getStatus())) {
throw new DisabledAccountException("帐号已经禁止登录!");
} else {
//更新登录时间 last login time
user.setLastLoginTime(new Date());
userService.updateByPrimaryKeySelective(user);
}
return new SimpleAuthenticationInfo(user, user.getPswd(), getName());
} /**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { Long userId = TokenManager.getUserId();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//根据用户ID查询角色(role),放入到Authorization里。
Set<String> roles = roleService.findRoleByUserId(userId);
info.setRoles(roles);
//根据用户ID查询权限(permission),放入到Authorization里。
Set<String> permissions = permissionService.findPermissionByUserId(userId);
info.setStringPermissions(permissions);
return info;
} /**
* 清空当前用户权限信息
*/
public void clearCachedAuthorizationInfo() {
PrincipalCollection principalCollection = SecurityUtils.getSubject().getPrincipals();
SimplePrincipalCollection principals = new SimplePrincipalCollection(
principalCollection, getName());
super.clearCachedAuthorizationInfo(principals);
} /**
* 指定principalCollection 清除
*/
public void clearCachedAuthorizationInfo(PrincipalCollection principalCollection) {
SimplePrincipalCollection principals = new SimplePrincipalCollection(
principalCollection, getName());
super.clearCachedAuthorizationInfo(principals);
}
}

关键点:doGetAuthenticationInfo(AuthenticationToken token)方法的返回值

return new SimpleAuthenticationInfo(user, user.getPswd(), getName());所以返回的token是一个user实体。

多realm以及jdbcRealm配置的更多相关文章

  1. 固定Realm 与配置数据库连接实现登录验证

    具体内容 在之前的shiro的认证都是基于配置文件完成的,但是在整个shiro之中,对于用户的认证信息可能各种途径,那么在shiro中要想实现从不同的途径中取得用户的身份认证就需要Realm了. 认识 ...

  2. shiro框架学习-4- Shiro内置JdbcRealm

    1.  JdbcRealm 数据库准备 JdbcRealm就是用户的角色,权限都从数据库中读取,也就是用来进行用户认证授权的安全数据源更换为从数据库中读取,其他没有差别,首先在数据库创建三张表: CR ...

  3. Shiro-多Realm验证

    1.多Realm验证 存在这样一种场景,同一个密码可能在MqSQL中存储,也可能在Oracle中存储,有可能MqSQL中使用的是MD5加密算法,而Oracle使用SHA1加密算法.这就需要有多个Rea ...

  4. Shiro-授权

    把 realms 配置给SecurityManager 在认证的时候单个realm是这样配置的: <bean id="securityManager" class=" ...

  5. Shiro的学习

    Apache Shiro 是 Java 的一个安全(权限)框架.它可以非常容易的开发出足够安全的应用,其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境 . Shiro 可以完成:认证 ...

  6. Shiro-RememberMe

    概述 认证和记住我 建议 身份验证相关 实现 如果要自己做RememeberMe,需要在登录之前创建Token:UsernamePasswordToken(用户名,密码,是否记住我),且调用 User ...

  7. SpringBoot整合Shiro权限框架实战

    什么是ACL和RBAC ACL Access Control list:访问控制列表 优点:简单易用,开发便捷 缺点:用户和权限直接挂钩,导致在授予时的复杂性,比较分散,不便于管理 例子:常见的文件系 ...

  8. Realm 配置

    快速入门 本文档介绍了如何借助一个“数据库”来配置 Tomcat ,从而实现容器管理安全性.所要连接的这种数据库含有用户名.密码以及用户角色.你只需知道的是,如果使用的 Web 应用含有一个或多个 & ...

  9. Shiro简单配置

    注:这里只介绍Spring配置模式. 因为官方例子虽然中有更加简洁的ini配置形式,但是使用ini配置无法与spring整合.而且两种配置方法一样,只是格式不一样. 涉及的jar包 核心包shiro- ...

随机推荐

  1. 20155331 2016-2017-2 《Java程序设计》

    20155331 2016-2017-2 <Java程序设计> 教材学习内容总结 理解封装,继承和多态. 封装最简单的理解就是包装,把编译的class文件封装起来,便于管理,还可以设置密码 ...

  2. Hadoop守护进程的作用(转)

    概述: <ignore_js_op> Hadoop是一个能够对大量数据进行分布式处理的软件框架,实现了Google的MapReduce编程模型和框架,能够把应用程序分割成许多的 小的工作单 ...

  3. Nginx入门篇(三)之虚拟主机配置

    一.虚拟主机概念 所谓虚拟主机,在Web服务当中就是一个独立的网站站点,这个站点对应独立的域名(也有可能是IP或者端口),具有独立的程序和资源目录,可以独立地对外提供服务供用户访问. 这个独立的站点在 ...

  4. EmitMapper自动映射工具

             在实体与DTO之间,我们一般都需要进行映射.如果手动的来进行转换,实在是太麻烦.所以就产生了很多映射工具,比如AutoMapper,EmitMapper.而经过一些对比,EmitMa ...

  5. 【MYSQL权限】数据库权限部署

    背景:没有划分数据库权限,所有人共用一个账号 本人公司现有的数据库账号分布情况: 所有人用一个账号(包括程序里面访问数据库的的配置文件里面的账号),该账号除删库权限,其他权限大部分都有. 这样非数据库 ...

  6. jenkins自动打包部署linux

    需要用到2个插件. git parameter:用于参数化构建时选择分支. Publish Over SSH:用于上传jar包和操作tomcat 1.先在系统设置添加要连接的linux服务器,使用用户 ...

  7. JAVA Date、String、Calendar类型之间的转化

    1.Calendar 转化 String //获取当前时间的具体情况,如年,月,日,week,date,分,秒等 Calendar calendat = Calendar.getInstance(); ...

  8. Qt creator 最常用的13个快捷键

    alt +enter // 自动创建类的定义 F1 // 查看帮助,文档 F2 // 快速到变量声明 Shift + F2 // 函数的声明和定义之间快速切换 F4 // 在 cpp 和 h 文件切换 ...

  9. C语言—单链表

    单链表操作:读取,插入和删除 #include "stdafx.h" #include <string.h> #include <stdio.h> #inc ...

  10. 深度学习-tensorflow学习笔记(2)-MNIST手写字体识别

    深度学习-tensorflow学习笔记(2)-MNIST手写字体识别超级详细版 这是tf入门的第一个例子.minst应该是内置的数据集. 前置知识在学习笔记(1)里面讲过了 这里直接上代码 # -*- ...