多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. C#基础之接口

    对于接口一直以来都清楚自己理解的不深入,这两天重温以前的代码时更加发现对接口的理解仅仅限于定义而已,得好好学学接口了. 1.接口的特点 接口的定义是指定一组函数成员而不实现成员的引用类型,其它类型和接 ...

  2. RHSCA模拟考试

    开始考试:桌面是个黑框子 点击reboot按钮,破解密码 开机成功,输入startx进入图形界面 不能复制,要在物理机用ssh root@172.25.0.11 远程连接,就可以复制粘贴了 * Hos ...

  3. ABP 框架集成EF批量增加、删除、修改只针对使用mmsql的

    AppService 层使用nuget 添加 EFCore.BulkExtensions 引用 using Abp.Application.Services.Dto; using Abp.Domain ...

  4. MVC捕获数据保存时的具体字段验证错误代码

    ////捕获验证错误代码 //try //{ // // 调试写数据库 //} //catch (DbEntityValidationException dbEx) //{ //}

  5. MySQL5.6.14从安装到启动全过程

    1.下载 地址:http://dev.mysql.com/downloads/mysql/ 这里选择的是Linux-Generic平台,下载了MySQL-5.6.14-1.linux_glibc2.5 ...

  6. VMWARE网络配置内网与外网互ping

    新增网络适配器 设置自定义VMnet0 自动桥接 NAT的网络要配置网关 我们在CentOS中打开ifcfg-ens33文件(每个系统文件名都不同,但都是以ifcfg-ens33开头的文件),进行修改 ...

  7. mui搜索框 搜索点击事件

    <div class="mui-input-row mui-search"> <input type="search" class=" ...

  8. Tess4J -4.0.2- Linux 实践 [解决:Tess4J - Native library (linux-x86-64/libtesseract.so) not found in resource path]

    [本文编写于2018年7月5日] Tess4J是Tesseract的Java JNA wrapper.本文介绍了在CentOS 7 操作系统中使用Tess4J的步骤及注意事项.在正式开始之前,先花一点 ...

  9. 遗传算法中几种不同选择算子及Python实现

    前言 本文对遗传算法中的几种选择策略进行了总结, 其中包括: Proportionate Roulette Wheel Selection Linear Ranking Selection Expon ...

  10. JS 数组方法 array数组声明 元素的添加和删除 等

    声明数组 var arr1 = [1,2,3,4,5]; var arr2 = new Array(100); //声明长度为100的arr2数组. arr2=[]; arr2.length = 10 ...