多realm以及jdbcRealm配置
多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配置的更多相关文章
- 固定Realm 与配置数据库连接实现登录验证
具体内容 在之前的shiro的认证都是基于配置文件完成的,但是在整个shiro之中,对于用户的认证信息可能各种途径,那么在shiro中要想实现从不同的途径中取得用户的身份认证就需要Realm了. 认识 ...
- shiro框架学习-4- Shiro内置JdbcRealm
1. JdbcRealm 数据库准备 JdbcRealm就是用户的角色,权限都从数据库中读取,也就是用来进行用户认证授权的安全数据源更换为从数据库中读取,其他没有差别,首先在数据库创建三张表: CR ...
- Shiro-多Realm验证
1.多Realm验证 存在这样一种场景,同一个密码可能在MqSQL中存储,也可能在Oracle中存储,有可能MqSQL中使用的是MD5加密算法,而Oracle使用SHA1加密算法.这就需要有多个Rea ...
- Shiro-授权
把 realms 配置给SecurityManager 在认证的时候单个realm是这样配置的: <bean id="securityManager" class=" ...
- Shiro的学习
Apache Shiro 是 Java 的一个安全(权限)框架.它可以非常容易的开发出足够安全的应用,其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境 . Shiro 可以完成:认证 ...
- Shiro-RememberMe
概述 认证和记住我 建议 身份验证相关 实现 如果要自己做RememeberMe,需要在登录之前创建Token:UsernamePasswordToken(用户名,密码,是否记住我),且调用 User ...
- SpringBoot整合Shiro权限框架实战
什么是ACL和RBAC ACL Access Control list:访问控制列表 优点:简单易用,开发便捷 缺点:用户和权限直接挂钩,导致在授予时的复杂性,比较分散,不便于管理 例子:常见的文件系 ...
- Realm 配置
快速入门 本文档介绍了如何借助一个“数据库”来配置 Tomcat ,从而实现容器管理安全性.所要连接的这种数据库含有用户名.密码以及用户角色.你只需知道的是,如果使用的 Web 应用含有一个或多个 & ...
- Shiro简单配置
注:这里只介绍Spring配置模式. 因为官方例子虽然中有更加简洁的ini配置形式,但是使用ini配置无法与spring整合.而且两种配置方法一样,只是格式不一样. 涉及的jar包 核心包shiro- ...
随机推荐
- 20155336 2016-2017-2《Java程序设计》课程总结
20155336虎光元<Java程序设计>课程总结 一.每周作业 第一周学习总结:http://www.cnblogs.com/hxl681207/p/6457919.html 第二周学习 ...
- C#:在AnyCPU模式下使用CefSharp
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客讲述如何在AnyCPU模式下使用CefSharp 因为在某些情况下,不得不用AnyCPU,但是CefS ...
- 建表/修改表名/增加删除字段(MySql)
修改表名:alter table 旧表名 rename 新表名; 删除字段:alter table 表名 drop 字段名; 增加字段:alter table 表名 add 字段名 字段类型 [def ...
- 在CentOS 7下编译安装Nginx+PHP+MySQL环境
本文转载自:http://www.softeng.cn/?p=156,本文已获得作者授权,未经作者同意,不可转载. 1.前言 本文适合于已经对Linux操作系统具有基本操作经验,并且能够在Linux或 ...
- 工作中遇到的令人头疼的bug
工作中我们会遇到形形色色的bug,但是很多bug都可以调试很明显的看出来,这种bug解决起来我们不会那么头疼但是有些却让人头疼而捉急,特别是本地运行一切正常,上传服务器就会出现bug.现在我总结几个我 ...
- 【转载】IntelliJ IDEA 2017常用快捷键
IntelliJ IDEA 是一款致力于提供给开发工程师沉浸式编程体验的IDE工具,所以在其中提供了很多方便高效的快捷键,一旦熟练掌握,整个开发的效率和体验将大大提升.本文就按照笔者自己日常开发时的使 ...
- VMWARE网络配置内网与外网互ping
新增网络适配器 设置自定义VMnet0 自动桥接 NAT的网络要配置网关 我们在CentOS中打开ifcfg-ens33文件(每个系统文件名都不同,但都是以ifcfg-ens33开头的文件),进行修改 ...
- 基础的Servlet
1.认识Servlet 今天接触了Servlet,我就写了这篇Servlet的文章.首先,我们了解一下Servlet是什么: 这是百度百科的解释,我个人理解是可以用来前后端交互的一个东西,例如可以实现 ...
- Liunx expect 基础
a script for study except #!/usr/bin/expect 声明文件内的语法使用 expect 的语法来执行. send send: 向进程发送字符串,用于模拟用户的输入. ...
- ovs源码阅读--流表查询原理
背景 在ovs交换机中,报文的处理流程可以划分为一下三个步骤:协议解析,表项查找和动作执行,其中最耗时的步骤在于表项查找,往往一个流表中有数目巨大的表项,如何根据数据报文的信息快速的查找到对应的流表项 ...