shiro之AuthenticationStrategy认证策略

1、AuthenticationStrategy 是个无状态的组件,在认证过程当中会进行以下4次调用git

1.在全部Realm被调用以前github

2.在调用Realm的getAuthenticationInfo方法以前apache

3.在调用Realm的getAuthenticationInfo 方法以后ide

4.在全部Realm被调用以后 即实现AuthenticationStrategy接口的类都要实现如下四个方法:beforeAllAttempts,beforeAttempt,afterAttempt,afterAllAttempts测试

2、对于多realm配置,Shiro有3中认证策略的具体实现spa

AtLeastOneSuccessfulStrategy(默认):只要有一个Realm验证成功便可,和FirstSuccessfulStrategy不一样,返回全部Realm身份验证成功的认证信息;code

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

AllSuccessfulStrategy:全部Realm验证成功才算成功,且返回全部Realm身份验证成功的认证信息,若是有一个失败就失败了。接口

三测试用例ip

1.ini配置

[main]
#指定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
myRealm3=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm3
securityManager.realms=$myRealm1,$myRealm3

2.Realm定义

public class MyRealm1 implements Realm
{

    @Override
    public String getName()
    {
        return "myrealm1";
    }

    @Override
    public boolean supports(AuthenticationToken token)
    {
        return token instanceof UsernamePasswordToken; //仅支持UsernamePasswordToken类型的Token
    }

    @Override
    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {

        String username = (String)token.getPrincipal();  //获得用户名
        String password = new String((char[])token.getCredentials()); //获得密码
        if(!"zhang".equals(username))
        {
            throw new UnknownAccountException(); //若是用户名错误
        }
        if(!"123".equals(password))
        {
            throw new IncorrectCredentialsException(); //若是密码错误
        }
        //若是身份认证验证成功,返回一个AuthenticationInfo实现;
        return new SimpleAuthenticationInfo(username, password, getName());
    }
}
public class MyRealm3 implements Realm
{

    @Override
    public String getName()
    {
        return "myrealm3";
    }

    @Override
    public boolean supports(AuthenticationToken token)
    {
        return token instanceof UsernamePasswordToken; //仅支持UsernamePasswordToken类型的Token
    }

    @Override
    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {

        String username = (String)token.getPrincipal();  //获得用户名
        String password = new String((char[])token.getCredentials()); //获得密码
        if(!"zhang".equals(username))
        {
            throw new UnknownAccountException(); //若是用户名错误
        }
        if(!"123".equals(password))
        {
            throw new IncorrectCredentialsException(); //若是密码错误
        }
        //若是身份认证验证成功,返回一个AuthenticationInfo实现;
        return new SimpleAuthenticationInfo(username + "@163.com", password, getName());
    }
}
public class MyRealm4 implements Realm
{

    @Override
    public String getName()
    {
        return "myrealm4";
    }

    @Override
    public boolean supports(AuthenticationToken token)
    {
        return token instanceof UsernamePasswordToken; //仅支持UsernamePasswordToken类型的Token
    }

    @Override
    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {

        String username = (String)token.getPrincipal();  //获得用户名
        String password = new String((char[])token.getCredentials()); //获得密码
        if(!"zhang".equals(username))
        {
            throw new UnknownAccountException(); //若是用户名错误
        }
        if(!"123".equals(password))
        {
            throw new IncorrectCredentialsException(); //若是密码错误
        }
        //若是身份认证验证成功,返回一个AuthenticationInfo实现;
        return new SimpleAuthenticationInfo(username, password, getName());
    }
}

3.登陆逻辑

private void login(String configFile)
{
    //一、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
    Factory<org.apache.shiro.mgt.SecurityManager> factory =
        new IniSecurityManagerFactory(configFile);

    //二、获得SecurityManager实例 并绑定给SecurityUtils
    org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
    SecurityUtils.setSecurityManager(securityManager);

    //三、获得Subject及建立用户名/密码身份验证Token(即用户身份/凭证)
    Subject subject = SecurityUtils.getSubject();
    UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");

    subject.login(token);
}

4.测试AllSuccessfulStrategy成功:

@Test  
       public void testAllSuccessfulStrategyWithSuccess() {  
               login("classpath:shiro-authenticator-all-success.ini");  
               Subject subject = SecurityUtils.getSubject();  
               //获得一个身份集合,其包含了Realm验证成功的身份信息  
                 PrincipalCollection principalCollection = subject.getPrincipals();  
                 Assert.assertEquals(2, principalCollection.asList().size());  
          }

总结:PrincipalCollection principalCollection = subject.getPrincipals(); 由于myRealm1和myRealm4返回的身份同样因此输出时只返回一个,因此获得一个身份集合

相关文章
相关标签/搜索