30分钟了解Shiro与Springboot的多Realm基础配置
写在前面的话:
我之前写过两篇与shiro安全框架有关的博文,居然能够广受欢迎实在令人意外。说明大家在互联网时代大伙对于安全和登录都非常重视,无论是大型项目还是中小型业务,普遍都至少需要登录与认证的逻辑封装。相较于SpringSecurity而言,Shrio更轻量无过多依赖和便于独立部署的特点更收到开发者的欢迎。本篇博客只作为前两篇对于shiro使用的基础补充,我只谈谈如何在springboot项目中配置多角色验证。
一、场景介绍
假设在我们的项目中需要有前台用户登录和后台系统管理员登录两种验证方式。当然在传统的业务逻辑中用户和管理员可以使用不同的角色加以区分,假设现在的逻辑是用户与系统管理员分别保存在不同的表中并且也分别对应了不同的角色(role)与权限(permission)。换句话说,从业务上看相同的用户名和密码如果是在前台页面登录可能对应的是普通用户,从后台登录则对应某板块的系统管理。面对这样的需求我们可以在shiro框架中配置多个realm,再配合上认证策略来执行。
二、代码讲解
与单一realm相同,首先根据不同的登录认证要求创建不同的realm。这里只提供作为后台系统管理员的realm代码实例:
// 系统管理员专用
public class AdministratorRealm extends AuthorizingRealm {
@Autowired
private AdministratorRegisterService administratorRegisterService;
@Autowired
private PasswordSupport passwordSupport; @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
String username = (String) principals.getPrimaryPrincipal();
Administrator administrator = administratorRegisterService.getAdministratorByName(username);
for (Role r : administrator.getRoles()) {
authorizationInfo.addRole(r.getRoleName());
}
return authorizationInfo;
} @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
Administrator administrator = administratorRegisterService.getAdministratorByName(username);
if (administrator == null) {
throw new UnknownAccountException();
}
if (administrator.isLocked()) {
throw new LockedAccountException();
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(administrator.getUsername(),
administrator.getPassword(), ByteSource.Util.bytes(passwordSupport.credentialsSalt(administrator)),
getName()); return authenticationInfo;
} }
doGetAuthenticationInfo方法负责用户名和密码验证,doGetAuthorizationInfo方法负责角色和权限的分配, passwordSupport是一个自定义的类负责password加密和生成salt功能。
/**
* 密码辅助方法
*
* @author learnhow
*
*/
@Component
public class PasswordSupport {
public static final String ALGORITHM_NAME = "md5";
public static final int HASH_ITERATIONS = 2;/**
* 针对系统管理生成salt和加密密码
*
* @param administrator
*/
public void encryptPassword(Administrator administrator) {
administrator.setSalt(new SecureRandomNumberGenerator().nextBytes().toHex());
String newPassword = new SimpleHash(ALGORITHM_NAME, administrator.getPassword(),
ByteSource.Util.bytes(credentialsSalt(administrator)), HASH_ITERATIONS).toHex();
administrator.setPassword(newPassword);
}/**
* 对Administrator的salt生成规则
*
* @param administrator
* @return
*/
public String credentialsSalt(Administrator administrator) {
return administrator.getSalt() + administrator.getEmail();
}
}
AdministratorRegisterService是服务组件负责通过name从数据库中查询。
在Shiro中无论是单一realm还是多个realm都需要对SecurityManager进行配置。
@Configuration
public class ShiroConfig {
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName(PasswordSupport.ALGORITHM_NAME);
hashedCredentialsMatcher.setHashIterations(PasswordSupport.HASH_ITERATIONS);
return hashedCredentialsMatcher;
} @Bean
public AdministratorRealm getAdministatorRealm() {
AdministratorRealm realm = new AdministratorRealm();
realm.setName("AdministratorRealm");
realm.setCredentialsMatcher(hashedCredentialsMatcher());
return realm;
} @Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
ModularRealmAuthenticator modularRealmAuthenticator = new ModularRealmAuthenticator();
modularRealmAuthenticator.setAuthenticationStrategy(new FirstSuccessfulStrategy());
securityManager.setAuthenticator(modularRealmAuthenticator); List<Realm> realms = new ArrayList<>();
// TODO-多个realms进配置在这里
realms.add(getAdministatorRealm());
securityManager.setRealms(realms);
return securityManager;
}
}
ModularRealmAuthenticator的setAuthenticationStrategy方法中配置认证策略。Shiro提供了三种策略:AllSuccessFulStrategy, AtLeastOneSuccessFulAtrategy, FirstSuccessFulStrategy,默认使用AtLeastOneSuccessFulAtrategy,通常不需要特别配置。
三、注意事项
1.多realm认证只会抛出AuthenticationException,因此如果要想在外部判断到底是在认证的哪一步发生的错误需要自己定义一些异常类型。
2.shiro没有提供根据条件指定realm的功能,如果需要实现这样的功能只能通过继承与重写来实现,这里没有涉及需要深入探讨的同学最好根据自己的实际情况专门研究。
写在后面的话:
最近有不少朋友在看了我的博客以后加我的QQ或者发邮件要求提供演示源码,为了方便交流我索性建了一个技术交流群,今后有些源码我可能就放群资料里面了。当然之前的一些东西还在补充中,有些问题也希望大伙能共同交流。QQ群号:960652410
30分钟了解Shiro与Springboot的多Realm基础配置的更多相关文章
- 30分钟带你了解Springboot与Mybatis整合最佳实践
前言:Springboot怎么使用想必也无需我多言,Mybitas作为实用性极强的ORM框架也深受广大开发人员喜爱,有关如何整合它们的文章在网络上随处可见.但是今天我会从实战的角度出发,谈谈我对二者结 ...
- Shiro (Shiro + JWT + SpringBoot应用)
Shiro (Shiro + JWT + SpringBoot应用) 目录 Shiro (Shiro + JWT + SpringBoot应用) 1.Shiro的简介 2.Shiro + JWT + ...
- 转:30分钟了解Springboot整合Shiro
引自:30分钟了解Springboot整合Shiro 前言:06年7月的某日,不才创作了一篇题为<30分钟学会如何使用Shiro>的文章.不在意之间居然斩获了22万的阅读量,许多人因此加了 ...
- 30分钟学会如何使用Shiro
本篇内容大多总结自张开涛的<跟我学Shiro>原文地址:http://jinnianshilongnian.iteye.com/blog/2018936 我并没有全部看完,只是选择了一部分 ...
- 转:30分钟学会如何使用Shiro
引自:http://www.cnblogs.com/learnhow/p/5694876.html 本篇内容大多总结自张开涛的<跟我学Shiro>原文地址:http://jinniansh ...
- 30分钟学会如何使用Shiro(转自:http://www.cnblogs.com/learnhow/p/5694876.html)
本篇内容大多总结自张开涛的<跟我学Shiro>原文地址:http://jinnianshilongnian.iteye.com/blog/2018936 我并没有全部看完,只是选择了一部分 ...
- 30分钟学会如何使用Shiro(转)
本文转自http://www.cnblogs.com/learnhow/p/5694876.html 感谢作者 本篇内容大多总结自张开涛的<跟我学Shiro>原文地址:http://jin ...
- 30分钟学会如何使用Shiro(转)
本篇内容大多总结自张开涛的<跟我学Shiro>原文地址:http://jinnianshilongnian.iteye.com/blog/2018936 我并没有全部看完,只是选择了一部分 ...
- 30分钟学会使用Spring Web Services基础开发
时隔一年终于又推出了一篇30分钟系列,上一篇<30分钟学会反向Ajax>是2016年7月的事情了.时光荏苒,岁月穿梭.虽然一直还在从事Java方面的开发工作,但是私下其实更喜欢使用C++. ...
随机推荐
- Qt setMargin()和setSpacing() 的含义
mainLayout=newQVBoxLayout(this); mainLayout->setMargin(30); //表示控件与窗体的左右边距 mainLayout->setSpac ...
- Ants-穷举算法
package java操作excel; import java.util.Scanner; /** * Ants * n只蚂蚁以每秒1cm的速度在长为Lcm的竿子上爬行,当蚂蚁爬到端点就会掉下去,竿 ...
- php分层
表示层 UI 主要表示WEB方式,也可以表示成WINFORM方式.如果逻辑层相当强大和完善,无论表现层如何定义和更改,逻辑层都能完善地提供服务. 业务逻辑层 BLL ...
- 010-centos上安装matlab
#001-下载matlab_R2015b和破解文件(四个)到百度云盘上下载7.6g#002-上传matlab大文件先安装vm tools,然后直接复制到虚拟机桌面#003-挂载matlab镜像并安装m ...
- bootstrap3浏览器支持情况
Internet Explorer 8 和 9 是被支持的,但是还是有很多CSS3属性和HTML5元素 -- 例如,圆角矩形和投影 -- 是肯定不被支持的.另外,Internet Explorer 8 ...
- java多线程----拒绝策略
本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略介绍 ...
- 负载均衡之-LVS
负载均衡用的很多,这里对负载均衡做一个总结吧,总共包含下面几片博文. LVS负载均衡 keepalived负载均衡+高可用 haproxy负载均衡 nginx负载均衡 LVS负载均衡 LVS是章文嵩博 ...
- 散列表(HashTable)
散列表 i. 散列函数 i. 冲突解决 ii. 分离链表法 ii. 开放地址法 iii. 线性探测法 iii. 平方探测法 iii. 双散列 ii. 再散列 ii. 可扩散列 i. 装填因子:元素个数 ...
- 01: MySql简介
MySQL其他篇 目录: 参考网站 1.1 数据库介绍 1.2 视图 1.3 触发器 1.4 事物 1.1 数据库介绍返回顶部 1.什么是数据库? 1. 数据库(Database)是按照数据结构来组织 ...
- C_Learning(3)
/ 结构体 / 声明结构体类型的一般形式: struct 结构体名[--表示的是这个结构体的类型] { 成员列表 }; [不要漏掉这个";"] / 声明结构可以放在main函 ...