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++. ...
随机推荐
- unity3d-小案例之角色简单漫游
准备资源 我这里从网上下载一个角色模型,里面有一组动画.有站立.奔跑.杀怪等 我们来实现角色的前后左后移动,即键盘上的WSDA键,这里因为没有行走的动画.索性就用奔跑代替了!! 暂时先不计较代码冗余的 ...
- http协议基础(七)通用首部字段
通用首部字段的意思,就是:请求和响应报文双方都会使用的首部 1.Cache-Control 通过指定它的指令,能操作缓存的工作机制 指令参数是可选的,多个指令通过“,”分隔 Cache-Control ...
- OO第三次阶段性总结
一.规格化设计的历史以及人们重视的原因 发展历史 从20世纪60年代开始,就存在着许多不同的形式规格说明语言和软件开发方法.在形式规格说明领域一些最主要的发展过程列举如下: 1969-1972 C.A ...
- map() 方法
1. 方法概述 map() 方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组. 2. 例子 2.1 在字符串中使用map 在一个 String 上使用 map 方法获取字符串中每 ...
- 新浪微博 SAE
一.云平台中云是指互联网,网络的一种比喻说法,顾名思义,这种平台允许开发者们或是将写好的程序放在“云”里运行,或是使用“云”里提供的服务,或二者皆是. 二.开发类云平台比较: 1.鼻祖 GOOGLE ...
- kendo column chart
目录 1.用js操作chart, 2.tooltip template鼠标悬浮显示内容, 3.双坐标轴,axisCrossingValues: [0, 30],3指的是跨越横坐标轴标签项数,显示在右 ...
- Java的redis控制台-Jedis
jedis 源码地址:https://github.com/xetorthio/jedis
- zw版【转发·台湾nvp系列Delphi例程】HALCON Roberts1
zw版[转发·台湾nvp系列Delphi例程]HALCON Roberts1 procedure TForm1.Button1Click(Sender: TObject);var img, img1: ...
- javashop技术培训总结,架构介绍,Eop核心机制
javashop技术培训一.架构介绍1.Eop核心机制,基于spring的模板引擎.组件机制.上下文管理.数据库操作模板引擎负责站点页面的解析与展示组件机制使得可以在不改变核心代码的情况下实现对应用核 ...
- seo标题关键字描述字数限制Title,keywords,description长度最长多长 ?
seo标题关键字描述字数限制 seo优化各个搜索引擎收录Title,keywords,description长度最长多长 ?SEO网站优化中Title标签的作用为重中之重,好的Title也就成功了一半 ...