Shiro笔记(二)身份验证

一、核心代码

 @Test
public void helloWorldTest(){
IniSecurityManagerFactory factory =
new IniSecurityManagerFactory("classpath:shiro-jdbc-realm.ini");
SecurityManager manager = factory.getInstance();
//全局设置,一次即可
SecurityUtils.setSecurityManager(manager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token =
new UsernamePasswordToken("Peter", "123");
try{
subject.login(token);
}catch (AuthenticationException e){
e.printStackTrace();
} Assert.assertEquals(true,subject.isAuthenticated());
//退出登录
subject.logout();

shiro.ini文件:

[users]
Peter=
Tom=

二、身份认证流程:

Authenticator 可能会委托给相应的 AuthenticationStrategy 进行多 Realm 身份验证,默认
ModularRealmAuthenticator 会调用 AuthenticationStrategy 进行多 Realm 身份验证;
Authenticator 会把相应的 token 传入 Realm,从 Realm 获取身份验证信息

三、Realm

Shiro 从从 Realm 获取安全数据(如用户、角色、权限)

Reaml接口:

 public interface Realm {
//获得唯一的名字
String getName();
//判断此realm是否支持此token
boolean supports(AuthenticationToken token);
//获取token认证信息
AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException;
}

一)单Realm配置

 public class MyRealm implements Realm{

     public String getName() {
return "myRealm";
} public boolean supports(AuthenticationToken authenticationToken) {
//仅支持UsernamePasswordToken类型
return authenticationToken instanceof UsernamePasswordToken;
} public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//获取用户名
String username= (String) token.getPrincipal();
//获取密码
String password=new String((char[]) token.getCredentials());
if(!"Peter".equals(username)){
throw new UnknownAccountException();
}
if(!"123".equals(password)){
throw new IncorrectCredentialsException();
}
return new SimpleAuthenticationInfo(username,password,getName());
}
}

ini文件指定:

 myRealm=com.tang.shirotest.LoginLogoutTest
securityManager.realms=$myRealm

二)JDBC Realm的使用

 [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=jiapi1990
jdbcRealm.dataSource=$dataSource
securityManager.realms=$jdbcRealm

三)Authenticator及AuthenticationStrategy

Authenticator的职责是验证用户账号,接口为:

public interface Authenticator {
AuthenticationInfo authenticate(AuthenticationToken var1) throws AuthenticationException;
}

SecurityManager 接口继承了 Authenticator,另外还有一个 ModularRealmAuthenticator 实现,
其委托给多个 Realm 进行验证,验证规则通过 AuthenticationStrategy 接口指定,默认提供
的实现:
FirstSuccessfulStrategy:只要有一个 Realm 验证成功即可,只返回第一个 Realm 身份验证
成功的认证信息,其他的忽略;
AtLeastOneSuccessfulStrategy:只要有一个 Realm 验证成功即可,和 FirstSuccessfulStrategy
不同,返回所有 Realm 身份验证成功的认证信息;
AllSuccessfulStrategy:所有 Realm 验证成功才算成功,且返回所有 Realm 身份验证成功的
认证信息,如果有一个失败就失败了

ModularRealmAuthenticator 默认使用 AtLeastOneSuccessfulStrategy 策略。

ini文件:

 #指定 securityManager 的 authenticator 实现
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
securityManager.authenticator=$authenticator
#指定 securityManager.authenticator 的 authenticationStrategy
allSuccessfulStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategy
securityManager.authenticator.authenticationStrategy=$allSuccessfulStrategy
myRealm1=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm1
myRealm2=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm2
myRealm3=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm3
securityManager.realms=$myRealm1,$myRealm3

AuthenticationStrategy接口:

 public interface AuthenticationStrategy {
//在所有 Realm 验证之前调用
AuthenticationInfo beforeAllAttempts(Collection<? extends Realm> realms, AuthenticationToken token) throws AuthenticationException;
//在每个 Realm 之前调用
AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException;
//在每个 Realm 之后调用
AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t)
throws AuthenticationException;
////在所有 Realm 之后调用
AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException;
}

自定义实现:

 public class AtLeastTwoAuthenticatorStrategy extends AbstractAuthenticationStrategy {

     @Override
public AuthenticationInfo beforeAllAttempts(Collection<? extends Realm> realms, AuthenticationToken token) throws AuthenticationException {
return new SimpleAuthenticationInfo();//返回一个权限的认证信息
} @Override
public AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
return aggregate;//返回之前合并的
} @Override
public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {
AuthenticationInfo info;
if (singleRealmInfo == null) {
info = aggregateInfo;
} else {
if (aggregateInfo == null) {
info = singleRealmInfo;
} else {
info = merge(singleRealmInfo, aggregateInfo);
}
} return info;
} @Override
public AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
if (aggregate == null || CollectionUtils.isEmpty(aggregate.getPrincipals()) || aggregate.getPrincipals().getRealmNames().size() < 2) {
throw new AuthenticationException("Authentication token of type [" + token.getClass() + "] " +
"could not be authenticated by any configured realms. Please ensure that at least two realm can " +
"authenticate these tokens.");
} return aggregate;
}
}

Shiro笔记(二)身份验证的更多相关文章

  1. Shiro学习之身份验证

    身份验证,即在应用中谁能证明他就是他本人.一般提供如他们的身份ID一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明. 在shiro中,用户需要提供principals (身份)和cre ...

  2. Shiro:学习笔记(1)——身份验证

    Shiro——学习笔记(1) 1.核心概念 1.Shiro不会自己去维护用户.维护权限:这些需要我们自己去设计/提供:然后通过相应的接口注入给Shiro.2.应用代码直接交互的对象是Subject,也 ...

  3. 【二】shiro入门 之 身份验证

    大体步骤如下: 1.首先通过new IniSecurityManagerFactory 并指定一个ini 配置文件来创建一个SecurityManager工厂: 2.接着获取SecurityManag ...

  4. Shiro -- (二) 身份验证基本流程

    简介: 在 shiro 中,用户需要提供 principals (身份)和 credentials(证明)给 shiro,从而应用能验证用户身份: principals:身份,即主体的标识属性,可以是 ...

  5. shiro 简单的身份验证 案例

    Apache Shiro是Java的一个安全框架,Shiro可以帮助我们完成:认证.授权.加密.会话管理.与Web集成.缓存等. 简单的身份验证 项目目录: 首先,在shiro.ini里配置了用户名和 ...

  6. shiro系列二、身份验证和授权

    一.身份验证 先来看看身份验证的流程 流程如下: 1.首先调用Subject.login(token)进行登录,其会自动委托给Security Manager,调用之前必须通过SecurityUtil ...

  7. 跟开涛老师学shiro -- 身份验证

    身份验证,即在应用中谁能证明他就是他本人.一般提供如他们的身份ID一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明. 在shiro中,用户需要提供principals (身份)和cre ...

  8. 第二章:shiro身份验证

    身份验证,即在应用中谁能证明他就是他本人.一般提供如他们的身份ID一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明. 在shiro中,用户需要提供principals (身份)和cre ...

  9. shiro身份验证

    身份验证,即在应用中谁能证明他就是他本人.一般提供如他们的身份ID一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明. 在shiro中,用户需要提供principals (身份)和cre ...

  10. 第二章 身份验证——《跟我学Shiro》

    转发:https://www.iteye.com/blog/jinnianshilongnian-2019547 目录贴:跟我学Shiro目录贴 身份验证,即在应用中谁能证明他就是他本人.一般提供如他 ...

随机推荐

  1. springboot系列四、配置模板引擎、配置热部署

    一.配置模板引擎 在之前所见到的信息显示发现都是以 Rest 风格进行显示,但是很明显在实际的开发之中,所有数据的显示最终都应该交由页面完成,但是这个页面并不是*.jsp 页面,而是普通的*.html ...

  2. Vue.js——理解与创建使用

    Vue.js 概念:是一个轻巧.高性能.可组件化的MVVM库,同时拥有非常容易上手的API,作者是尤雨溪是中国人. 优点: 1)易用 已经会了HTML,CSS,JavaScript?即刻阅读指南开始构 ...

  3. zabbix3.0对tcp连接数和状态的监控优化

    zabbix3.0对tcp连接数及状态的监控优化 之前对tcp的监控采用netstat命令,发现在服务器繁忙的时候效果不理想,这个命令占用大量的cpu有时候高达90%以上,可能会导致业务的不稳定,所以 ...

  4. OA系统高性能解决方案(史上最全的通达OA系统优化方案)

    序: 这是一篇针对通达OA系统的整体优化方案,文档将硬件.网络.linux操作系统.程序本身(包括web和数据库)以及现有业务有效结合在一起,进行了系统的整合优化.该方案应用于真实生产环境,部署完成后 ...

  5. 转载:2.2.5 在配置中使用变量《深入理解Nginx》(陶辉)

    原文:https://book.2cto.com/201304/19630.html 有些模块允许在配置项中使用变量,如在日志记录部分,具体示例如下.log_format  main  '$remot ...

  6. 转载:磁盘目录(1.3.3)《深入理解Nginx》(陶辉)

    原文:https://book.2cto.com/201304/19614.html 要使用Nginx,还需要在Linux文件系统上准备以下目录. (1)Nginx源代码存放目录 该目录用于放置从官网 ...

  7. Weex学习资料整合

    1.weex weex文档:http://weex.apache.org/cn/guide/index.html Weex Ui awesome-weex WEEX免费视频教程-从入门到放肆 (共17 ...

  8. 经典SQL语句大全(转)

    SQL语句参考,包含Access.MySQL 以及 SQL Server 基础 创建数据库 CREATE DATABASE database-name 删除数据库 drop database dbna ...

  9. Android学习笔记————利用JDBC连接服务器数据库

    /******************************************************************************************** * auth ...

  10. Android动画分类

    动画分类 View动画(补间动画).帧动画.属性动画 View动画(补间动画)包括:平移.旋转.缩放.透明度,View动画是一种渐近式动画 帧动画:图片切换动画 属性动画:通过动态改变对象的属性达到动 ...