Shrio03 Authenticator、配置多個Realm、SecurityManager認證策略

1 Authenticator 簡介

1.1 層次結構圖

1.2 做用

職責是驗證用戶賬號,是ShiroAPI中身份驗證核心的入口點;接口中聲明的authenticate方法就是用來實現認證邏輯的。java

1.3 源代碼

1.4 authenticate

》該方法是實現認證邏輯的。
》若是驗證成功,將返回AuthenticationInfo驗證信息;此信息中包含了身份及憑證;若是驗證失敗將拋出相應的 AuthenticationException 實現。 apache

2 ModularRealmAuthenticator

2.1 關係圖

2.2 做用

認證策略接口,自定義認證策略時只須要繼承該類便可(PS:通常使用默認的三種策略便可)spa

2.3 三種策略

》FirstSuccessfulStrategy:只要有一個Realm驗證成功便可,只返回第一個Realm身份驗證 成功的認證信息,其餘的忽略;
》AtLeastOneSuccessfulStrategy:只要有一個Realm驗證成功便可,和FirstSuccessfulStrategy 不一樣,返回全部 Realm 身份驗證成功的認證信息;
》AllSuccessfulStrategy:全部Realm驗證成功纔算成功,且返回全部Realm身份驗證成功的 認證信息,若是有一個失敗就失敗了。
》注意:ModularRealmAuthenticator 默認使用 AtLeastOneSuccessfulStrategy 策略。 3d

3 代碼實現

3.1 環境搭建

建立一個Maven項目,並引入shiro、junit相關依賴code

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

3.2 自定義Realm

》實現Realm接口便可
》MyRealm01orm

package com.xunyji.shirotest.realm;

import org.apache.shiro.authc.*;
import org.apache.shiro.realm.Realm;

/**
 * @author AltEnter
 * @create 2019-01-21 16:21
 * @desc 簡易Realm01
 **/
public class MyRealm01 implements Realm {
    
    /** 用戶名 */
    public static final String USERNAME = "fury1";
    /** 用戶密碼 */
    public static final String PASSWORD = "111111";

    public String getName() {
        return "MyRealm01";
    }

    public boolean supports(AuthenticationToken token) {
        if (token instanceof UsernamePasswordToken) {
            return true;
        }
        return false;
    }

    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());
        if (USERNAME.equals(username) && PASSWORD.equals(password)) {
            return new SimpleAuthenticationInfo(username, password, getName());
        } else {
            throw new RuntimeException("MyRealm01 - 用戶名或者密碼錯誤");
        }
    }

}

》MyRealm02對象

package com.xunyji.shirotest.realm;

import org.apache.shiro.authc.*;
import org.apache.shiro.realm.Realm;

/**
 * @author AltEnter
 * @create 2019-01-21 16:21
 * @desc 簡易Realm01
 **/
public class MyRealm02 implements Realm {
    
    /** 用戶名 */
    public static final String USERNAME = "fury2";
    /** 用戶密碼 */
    public static final String PASSWORD = "222222";

    public String getName() {
        return "MyRealm02";
    }

    public boolean supports(AuthenticationToken token) {
        if (token instanceof UsernamePasswordToken) {
            return true;
        }
        return false;
    }

    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());
        if (USERNAME.equals(username) && PASSWORD.equals(password)) {
            return new SimpleAuthenticationInfo(username, password, getName());
        } else {
            throw new RuntimeException("MyRealm02 - 用戶名或者密碼錯誤");
        }
    }

}

3.3 思路

》實例化Realm
》實例化SecurityManager
》實例化ModularRealmAuthenticator
》實例化FirstSuccessfulStrategy
》給ModularRealmAuthenticator對象設置認證策略
》給SecurityManager設置認證對象
》給SecurityManager設置Realm對象
》注意:SecurityManager必須先設置Authenticator再設置Realm,不然會報錯blog

3.4 源代碼

package com.xunyji.shirotest.autenticatedemo;

import com.xunyji.shirotest.realm.MyRealm01;
import com.xunyji.shirotest.realm.MyRealm02;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.pam.AllSuccessfulStrategy;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.authc.pam.FirstSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * @author AltEnter
 * @create 2019-01-21 16:26
 * @desc
 **/
public class TestDemo {
    @Test
    public void test01() {
//        01 獲取Realm對象
        MyRealm01 myRealm01 = new MyRealm01();
        MyRealm02 myRealm02 = new MyRealm02();

//        02 獲取SecurityManager對象
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//        03 設置SecurityManager對象的認證策略
        ModularRealmAuthenticator modularRealmAuthenticator = new ModularRealmAuthenticator();
        modularRealmAuthenticator.setAuthenticationStrategy(new FirstSuccessfulStrategy());
//        modularRealmAuthenticator.setAuthenticationStrategy(new AllSuccessfulStrategy());
        defaultSecurityManager.setAuthenticator(modularRealmAuthenticator);

//        04 設置SecurityManager的Realm
//        defaultSecurityManager.setRealm(myRealm01);
//        defaultSecurityManager.setRealm(myRealm02);
        Set<Realm> realmHashSet = new HashSet<Realm>();
        realmHashSet.add(myRealm01);
        realmHashSet.add(myRealm02);
        defaultSecurityManager.setRealms(realmHashSet);

        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token = new UsernamePasswordToken("fury1", "111111");
//        UsernamePasswordToken token = new UsernamePasswordToken("fury2", "222222");

        subject.login(token);

        System.out.println(String.format("認證結果爲:%s", subject.isAuthenticated()));

        subject.logout();

        System.out.println(String.format("認證結果爲:%s", subject.isAuthenticated()));

    } 
}

 

相關文章
相關標籤/搜索