2.1shiro身份认证的策略分析

shiro身份认证的策略分析

1.Authenticator 及 AuthenticationStrategy

Authenticator 的职责是验证用户帐号,是 Shiro API 中身份验证核心的入口点:

public AuthenticationInfo authenticate(AuthenticationToken authenticationToken)
            throws AuthenticationException;

如果验证成功,将返回 AuthenticationInfo 验证信息;此信息中包含了身份及凭证;如果验证失败将抛出相应的 AuthenticationException 实现。

1.SecurityManager 接口继承了 Authenticator默认实现为ModularRealmAuthenticator

ModularRealmAuthenticator 实现,其委托给多个 Realm 进行验证,验证规则通过 AuthenticationStrategy 接口指定,默认使用AtLeastOneSuccessfulStrategy 策略。

2.三个验证策略

FirstSuccessfulStrategy:只要有一个 Realm 验证成功即可,只返回第一个 Realm 身份验证成功的认证信息,其他的忽略;

AtLeastOneSuccessfulStrategy:只要有一个 Realm 验证成功即可,和 FirstSuccessfulStrategy 不同,返回所有 Realm 身份验证成功的认证信息;

AllSuccessfulStrategy:所有 Realm 验证成功才算成功,且返回所有 Realm 身份验证成功的认证信息,如果有一个失败就失败了。

2.配置实现策略

2.1使用FirstSuccessfulStrategy策略

shiro.ini文件

[main]
#指定securityManager的authenticator实现
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
securityManager.authenticator=$authenticator

#指定securityManager.authenticator的authenticationStrategy
firstSuccessfulStrategy=org.apache.shiro.authc.pam.FirstSuccessfulStrategy
securityManager.authenticator.authenticationStrategy=firstSuccessfulStrategy

myRealm1=com.github.shiro.realm.MyRealm1
myRealm2=com.github.shiro.realm.MyRealm2
myRealm3=com.github.shiro.realm.MyRealm3
securityManager.realms=$myRealm1,$myRealm2,$myRealm3

2.2使用AtLeastOneSuccessfulStrategy策略

同上,只修改securityManager.authenticator的authenticationStrategy

2.3使用AllSuccessfulStrategy策略

同上,只修改securityManager.authenticator的authenticationStrategy

3.自定义身份认证策略

自定义 AuthenticationStrategy 实现,首先看其 API:

//在所有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;

3.1实现过程

1)实现至少两认证成功

  1. 继承AbstractAuthenticationStrategy 并重写方法afterAllAttempts
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;
    }
}

2.修改shiro.ini文件

#指定securityManager.authenticator的authenticationStrategy
atLeastTwoAuthenticatorStrategy=com.github.shiro.authenticator.strategy.AtLeastTwoAuthenticatorStrategy
securityManager.authenticator.authenticationStrategy=atLeastTwoAuthenticatorStrategy

猜你喜欢

转载自blog.csdn.net/c_royi/article/details/80854851
今日推荐