相关阅读
简介
鉴权策略的实现类帮助ModularRealmAuthenticator
在可插拔Realm
环境(PAM)中处理登录请求;
核心方法
/**
* 鉴权过程预处理
*/
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;
/**
* 鉴权过程后处理
*/
AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException;
使用场景
ModularRealmAuthenticator.doMultiRealmAuthentication
方法中使用,代码如下:
protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {
AuthenticationStrategy strategy = getAuthenticationStrategy();
// 鉴权预处理,简单返回初始聚合结果
AuthenticationInfo aggregate = strategy.beforeAllAttempts(realms, token);
if (log.isTraceEnabled()) {
log.trace("Iterating through {} realms for PAM authentication", realms.size());
}
// 遍历配置的realm
for (Realm realm : realms) {
try {
// realm鉴权预处理
aggregate = strategy.beforeAttempt(realm, token, aggregate);
} catch (ShortCircuitIterationException shortCircuitSignal) {
// 无需继续鉴权
// Break from continuing with subsequnet realms on receiving
// short circuit signal from strategy
break;
}
if (realm.supports(token)) {
log.trace("Attempting to authenticate token [{}] using realm [{}]", token, realm);
AuthenticationInfo info = null;
Throwable t = null;
try {
info = realm.getAuthenticationInfo(token);
} catch (Throwable throwable) {
t = throwable;
if (log.isDebugEnabled()) {
String msg = "Realm [" + realm + "] threw an exception during a multi-realm authentication attempt:";
log.debug(msg, t);
}
}
// realm鉴权后处理,处理鉴权过程中抛出的异常以及合并鉴权后的账户数据
aggregate = strategy.afterAttempt(realm, token, info, aggregate, t);
} else {
log.debug("Realm [{}] does not support token {}. Skipping realm.", realm, token);
}
}
// 鉴权后处理
aggregate = strategy.afterAllAttempts(token, aggregate);
return aggregate;
}
实现子类
public interface AuthenticationStrategy
public abstract class AbstractAuthenticationStrategy implements AuthenticationStrategy
public class AtLeastOneSuccessfulStrategy extends AbstractAuthenticationStrategy
public class AllSuccessfulStrategy extends AbstractAuthenticationStrategy
public class FirstSuccessfulStrategy extends AbstractAuthenticationStrategy
AbstractAuthenticationStrategy
简介
Shiro具体的鉴权策略实现的抽象基础实现;
核心方法
/**
* 鉴权过程预处理
* 简单返回支持跨realm聚合账户数据的SimpleAuthenticationInfo
*/
public AuthenticationInfo beforeAllAttempts(Collection<? extends Realm> realms, AuthenticationToken token) throws AuthenticationException {
return new SimpleAuthenticationInfo();
}
/**
* realm预鉴权处理
* 简单返回聚合账户数据
*/
public AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
return aggregate;
}
/**
* realm后鉴权处理
* 聚合单个领域的账户数据的基本实现
*/
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;
}
/**
* 聚合账户数据
*/
protected AuthenticationInfo merge(AuthenticationInfo info, AuthenticationInfo aggregate) {
if( aggregate instanceof MergableAuthenticationInfo ) {
((MergableAuthenticationInfo)aggregate).merge(info);
return aggregate;
} else {
throw new IllegalArgumentException( "Attempt to merge authentication info from multiple realms, but aggregate " +
"AuthenticationInfo is not of type MergableAuthenticationInfo." );
}
}
/**
* 鉴权过程后处理
* 简单返回聚合账户数据
*/
public AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
return aggregate;
}
AtLeastOneSuccessfulStrategy
简介
只要有一个配置的Realm
鉴权通过则判定登录成功,保留所有鉴权通过的账号数据;
核心方法
/**
* 鉴权过程后处理
* 如果聚合账户数据为空,则表示所有realm鉴权失败
*/
public AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
//we know if one or more were able to successfully authenticate if the aggregated account object does not
//contain null or empty data:
if (aggregate == null || isEmpty(aggregate.getPrincipals())) {
throw new AuthenticationException("Authentication token of type [" + token.getClass() + "] " +
"could not be authenticated by any configured realms. Please ensure that at least one realm can " +
"authenticate these tokens.");
}
return aggregate;
}
AllSuccessfulStrategy
简介
所有配置的Realm
鉴权通过则判定登录成功;
核心方法
/**
* realm预鉴权处理
* 校验当前realm是否支持该token
*/
public AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException {
if (!realm.supports(token)) {
String msg = "Realm [" + realm + "] of type [" + realm.getClass().getName() + "] does not support " +
" the submitted AuthenticationToken [" + token + "]. The [" + getClass().getName() +
"] implementation requires all configured realm(s) to support and be able to process the submitted " +
"AuthenticationToken.";
throw new UnsupportedTokenException(msg);
}
return info;
}
/**
* realm后鉴权处理
* 聚合单个领域的账户数据前会额外校验
* 1. 异常信息不为null,则立即抛出异常
* 2. 账户数据为null,则立即抛出异常
*/
public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo info, AuthenticationInfo aggregate, Throwable t)
throws AuthenticationException {
// 异常信息不为null
if (t != null) {
if (t instanceof AuthenticationException) {
//propagate:
throw ((AuthenticationException) t);
} else {
String msg = "Unable to acquire account data from realm [" + realm + "]. The [" +
getClass().getName() + " implementation requires all configured realm(s) to operate successfully " +
"for a successful authentication.";
throw new AuthenticationException(msg, t);
}
}
// 账户数据为null
if (info == null) {
String msg = "Realm [" + realm + "] could not find any associated account data for the submitted " +
"AuthenticationToken [" + token + "]. The [" + getClass().getName() + "] implementation requires " +
"all configured realm(s) to acquire valid account data for a submitted token during the " +
"log-in process.";
throw new UnknownAccountException(msg);
}
log.debug("Account successfully authenticated using realm [{}]", realm);
// If non-null account is returned, then the realm was able to authenticate the
// user - so merge the account with any accumulated before:
merge(info, aggregate);
return aggregate;
}
FirstSuccessfulStrategy
简介
只要有一个配置的Realm
鉴权通过则判定登录成功,只保留第一个鉴权通过的账户数据;
核心方法
// 停止标识
private boolean stopAfterFirstSuccess;
/**
* 鉴权过程预处理
* 简单返回null
*/
public AuthenticationInfo beforeAllAttempts(Collection<? extends Realm> realms, AuthenticationToken token) throws AuthenticationException {
return null;
}
/**
* realm预鉴权处理
* 如果设置停止标识,那么只要鉴权通过则抛出ShortCircuitIterationException异常
*/
public AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
if (getStopAfterFirstSuccess() && aggregate != null && !isEmpty(aggregate.getPrincipals())) {
throw new ShortCircuitIterationException();
}
return aggregate;
}
/**
* 聚合账户数据
*/
protected AuthenticationInfo merge(AuthenticationInfo info, AuthenticationInfo aggregate) {
// 如果聚合结果有效则直接返回
if (aggregate != null && !isEmpty(aggregate.getPrincipals())) {
return aggregate;
}
return info != null ? info : aggregate;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/4792.html