美文网首页
Authenticator及AutenticationStrat

Authenticator及AutenticationStrat

作者: tingshuo123 | 来源:发表于2018-08-23 22:41 被阅读29次

    身份认证流程

    流程图.png

    流程如下:

    1. 通过Subject对象的login(token)方法登录,其会委托给Security Manager
    2. SecurityManager负责正的身份验证逻辑,它会委托给Authenticator进行身份验证;
    3. Autenticator才是真正的身份验证者,此处可自己实现。
    4. Autenticator可能会委托给 AuthenticationStrategy进行多 Realm 身份验证
    5. Autenticator 会把登录时传入的token对象,传给 Realm,验证成功后会返回AuthenticationInfo对象,此对象中包含用户的身份及凭证,如果认证失败会抛出AuthenticationException异常。此处可以配置多个 Realm,将按照相应的顺序及策略进行验证。

    Authenticator

    Authenticator有多种已实现的验证规则,可以通过 AuthenticationStrategy 接口指定,已经实现的验证规则有:

    认证策略:

    • FirstSuccessfulStrategy:通过有一个Realm验证即通过验证,会返回第一个通过的Realm认证信息
    • AtLeastOneSuccessfulStrategy:同样一个通过即可,但是这个会返回所有Realm 身份验证成功的认证信息
    • AllSuccessfulStrategy:这个比较严厉,要通过所有的 Realm 验证才算成功,且返回所有的Realm 的认证信息

    默认使用的是 AtLeastOneSuccessfulStrategy 验证策略;

    代码实例

    创建三个自定义的 Realm:

    myRealm1: 用户名 / 密码为 admin/ad123 时成功,且返回身份 / 凭据为 admin/ad123;

    myRealm2: 用户名 / 密码为 admin2/123 时成功,且返回身份 / 凭据为 admin2/ad123;

    myRealm3: 用户名 / 密码为 admin/ad123 时成功,且返回身份 / 凭据为admin@163.com/123

    myRealm1:

    package shiro02;
    
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.realm.Realm;
    
    public class MyRealm1 implements Realm {
    
        @Override
        public String getName() {
    
            return "MyRealm1";
        }
    
        @Override
        public boolean supports(AuthenticationToken token) {
    
            return token instanceof UsernamePasswordToken;
        }
    
        @Override
        public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            // 获取用户名跟密码
            String username = (String) token.getPrincipal();
            String password = new String((char[]) token.getCredentials());
    
            // 如果用户名错误
            if (!"admin".equals(username)) {
                throw new UnknownAccountException();
            }
    
            // 如果密码错误
            if (!"ad123".equals(password)) {
                throw new IncorrectCredentialsException();
            }
    
            // 验证通过
            return new SimpleAuthenticationInfo(username, password, getName());
        }
    
    }
    

    myRealm2 改变上面用户名与密码的字符串
    myRealm3 将 return 语句改成 return new SimpleAuthenticationInfo(username + "@163.com", password, getName());

    配置文件

    shiro-authenticator-all-success.ini

    #指定SecurityManager的authenticator实现
    authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
    securityManager.authenticator=$authenticator
    
    # 声明验证策略
    allSuccessfulStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategy
    # 指定策略
    securityManager.authenticator.authenticationStrategy=$allSuccessfulStrategy
    
    # 声明 realm
    myRealm1=shiro02.MyRealm1
    myRealm2=shiro02.MyRealm2
    myRealm3=shiro02.MyRealm3
    # 指定多个 realm
    securityManager.realms=$myRealm1,$myRealm3
    
    测试
    package shiro02;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.util.Factory;
    import org.junit.Test;
    
    public class AuthenticatorTest {
        
        private void login(String configFile) {
            // 获取SecurityManager工厂
            Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory(
                    configFile);
    
            // 获通过工厂获取SecurityManager实例
            SecurityManager securityManager = factory.getInstance();
    
            // 将实例绑定给SecurityUtils
            SecurityUtils.setSecurityManager(securityManager);
    
            // 获取Subject
            Subject subject = SecurityUtils.getSubject();
    
            // 创建Token
            UsernamePasswordToken token = new UsernamePasswordToken("admin", "ad123");
    
            // 登录(验证用户)
            try {
                subject.login(token);
            } catch (AuthenticationException e) {
                // 验证失败
                e.printStackTrace();
            }
    
            if (subject.isAuthenticated()) {
                System.out.println("登录成功!!!");
            }
        }
        
        @Test
        public void testAllSuccessfulStrategyWithSuccess() {
            this.login("classpath:shiro-authenticator-all-success.ini");
            Subject subject = SecurityUtils.getSubject();
            
            // 得到身份集合,包含Realm验证成功的身份信息
            PrincipalCollection principalCollection = subject.getPrincipals();
            System.out.println(principalCollection.asList());
        }
    }
    

    相关文章

      网友评论

          本文标题:Authenticator及AutenticationStrat

          本文链接:https://www.haomeiwen.com/subject/foqviftx.html