cas-server之認(rèn)證核心接口AuthenticationManager

該接口是cas-server認(rèn)證入口,但從唯一實(shí)現(xiàn)類(lèi)來(lái)看,它并不是認(rèn)證執(zhí)行者,執(zhí)行者是AuthenticationHandler,該接口控制認(rèn)證流程,包括異常處理和結(jié)果封裝,將認(rèn)證結(jié)果封裝成Authentication返回。

public interface AuthenticationManager {
     //有一個(gè)Credential認(rèn)證成功返回Authentication,所有Credential都認(rèn)證失敗拋出AuthenticationException
    Authentication authenticate(AuthenticationTransaction authenticationTransaction) throws AuthenticationException;
}

唯一實(shí)現(xiàn)PolicyBasedAuthenticationManager

核心代碼

AuthenticationBuilder builder = new DefaultAuthenticationBuilder(NullPrincipal.getInstance());
builder.addCredential(new BasicCredentialMetaData(credential));
//執(zhí)行認(rèn)證
HandlerResult result = authenticationHandler.authenticate(credential);
//一個(gè)credential認(rèn)證成功
builder.addSuccess(authenticationHandler.getName(), result);
//一個(gè)credential認(rèn)證失敗
builder.addFailure(authenticationHandler.getName(), e.getClass());

//credential解析,Principal才是客戶真正需要的
Principal principal = principalResolver.resolve(credential);
builder.setPrincipal(principal);

//構(gòu)建authentication  
Authentication authentication  = builder.build();

//那些情況拋出AuthenticationException?
//一個(gè)credential都沒(méi)認(rèn)證成功
if (builder.getSuccesses().isEmpty()) {
  throw new AuthenticationException(builder.getFailures(), builder.getSuccesses());
 }
//不滿足認(rèn)證安全策略
if (!this.authenticationPolicy.isSatisfiedBy(builder.build())) {
    throw new AuthenticationException(builder.getFailures(), builder.getSuccesses());
}
//空Principal
if (principal instanceof NullPrincipal) {
    throw new UnresolvedPrincipalException(authentication);
 }

相關(guān)接口

Principal

客戶端拿著serviceTicket來(lái)驗(yàn)證時(shí),驗(yàn)證通過(guò),服務(wù)器會(huì)返回一個(gè)Principal實(shí)現(xiàn),默認(rèn)只返回Principal的id,也可以附帶返回attributes,需要自己修改xml(jsp)

  • SimplePrincipal
    簡(jiǎn)單實(shí)現(xiàn),有id和attributes,沒(méi)有其他東西
  • NullPrincipal
    一個(gè)空實(shí)現(xiàn),id固定為字符串nobody,attributes為一個(gè)EmptyMap實(shí)例
  • WebApplicationService
    這個(gè)實(shí)現(xiàn)Principal比較奇怪,跟Principal的含義沒(méi)半毛錢(qián)關(guān)系,只是要用到id屬性,關(guān)于WebApplicationService 后面再寫(xiě)

Credential

可以把它看成用戶登錄時(shí)輸入登錄信息的實(shí)體,實(shí)際上它就是表示這個(gè)意思??纯磳?shí)現(xiàn)就知道了

  • UsernamePasswordCredential
    包含username、password基本的登錄信息,系統(tǒng)默認(rèn)用這個(gè),可看WEB-INF/webflow/login/login-webflow.xml
  • RememberMeUsernamePasswordCredential
    繼承UsernamePasswordCredential ,增加了rememberMe,是不是登錄時(shí)候的那些東西
  • BasicIdentifiableCredential
    這個(gè)更簡(jiǎn)潔,只有一個(gè)id屬性,系統(tǒng)沒(méi)有那個(gè)地方用到它
  • OneTimePasswordCredential
    一次性密碼,系統(tǒng)也沒(méi)有地方使用
  • HttpBasedServiceCredential
    通過(guò)回調(diào)callbackUrl來(lái)驗(yàn)證,回調(diào)成功表示驗(yàn)證通過(guò),該Credential 綁定了關(guān)聯(lián)的registeredService,getId返回的是callbackUrl字符串。

AuthenticationHandler

認(rèn)證的執(zhí)行者,類(lèi)似dao,會(huì)跟數(shù)據(jù)源打交道

  • HttpBasedServiceCredentialsAuthenticationHandler
    代理認(rèn)證,用于HttpBasedServiceCredential認(rèn)證,里面有一個(gè)HttpClient(注入),當(dāng)RegisteredService的ProxyPolicy接受CallbackUrl且HttpClient請(qǐng)求CallbackUrl成功(返回指定的code)表示認(rèn)證通過(guò)
  • AbstractUsernamePasswordAuthenticationHandler
    抽象類(lèi),用于UsernamePasswordCredential的認(rèn)證,子類(lèi)一般會(huì)使用外部數(shù)據(jù)源查庫(kù),如使用JDBC,只需依賴cas-server-support-jdbc支持。
  • JaasAuthenticationHandler
    使用JAAS認(rèn)證,用的不多,具體配置可以看源碼
  • AcceptUsersAuthenticationHandler
    接受一個(gè)靜態(tài)的用戶數(shù)據(jù)驗(yàn)證,默認(rèn)去cas.properties中accept.authn.users值進(jìn)行校驗(yàn),系統(tǒng)默認(rèn)用這種方式,實(shí)際中肯定要換成第三方數(shù)據(jù)源的。

PrincipalResolver

從給定的credential解析出一個(gè)Principal

  • PersonDirectoryPrincipalResolver
    使用Jasig Person Directory庫(kù)解析,當(dāng)客戶端除了需要id外,還需要更多的用戶屬性時(shí),推薦使用這個(gè)。通過(guò)使用IPersonAttributeDao返回Map<String, List<Object>>里面可存放關(guān)聯(lián)的屬性。默認(rèn)的實(shí)現(xiàn)StubPersonAttributeDao只是簡(jiǎn)單的維護(hù)了一個(gè)靜態(tài)backingMap,實(shí)際中建議連接數(shù)據(jù)源進(jìn)行動(dòng)態(tài)查詢,具體可看IPersonAttributeDao實(shí)現(xiàn)。
  • BasicPrincipalResolver
    解析工作完全委托給PrincipalFactory,自己什么也不做

AuthenticationPolicy

安全策略檢查,相當(dāng)于這里設(shè)置最后一道關(guān)卡,檢查Authentication的合法性,如果沒(méi)有特別的需求用默認(rèn)的即可

  • AnyAuthenticationPolicy
    類(lèi)里有一個(gè)標(biāo)志位tryAll,取cas.properties中cas.authn.policy.any.tryall值,默認(rèn)false
    true:Authentication在Credentials數(shù)量必須等于Successes+Failures的數(shù)量
    false:Successes不為空就行
  • NotPreventedAuthenticationPolicy
    繼承AnyAuthenticationPolicy
  • AllAuthenticationPolicy,增加了一個(gè)條件
  public boolean isSatisfiedBy(final Authentication authentication) {
        for (final String handler : authentication.getFailures().keySet()) {
            if (authentication.getFailures().get(handler).isAssignableFrom(PreventedException.class)) {
                return false;
            }
        }
        return super.isSatisfiedBy(authentication);
    }
  • RequiredHandlerAuthenticationPolicy
//requiredHandlerName值取cas.properties中cas.authn.policy.req.handlername,默認(rèn)handlerName,tryAll取cas.authn.policy.req.tryall,默認(rèn)false
public boolean isSatisfiedBy(final Authentication authn) {
        boolean credsOk = true;
        if (this.tryAll) {
            credsOk = authn.getCredentials().size() == authn.getSuccesses().size() + authn.getFailures().size();
        }
        return credsOk && StringUtils.isNotBlank(this.requiredHandlerName) && authn.getSuccesses().containsKey(this.requiredHandlerName);
    }
  • ContextualAuthenticationPolicy
    接口,更復(fù)雜的校驗(yàn),如獲取某一個(gè)策略Context檢驗(yàn)Authentication,具體Context看具體實(shí)現(xiàn)

至此cas-server的Credential 認(rèn)證部分就這些內(nèi)容了,看起來(lái)比較簡(jiǎn)單,但這種架構(gòu)設(shè)計(jì)非常值得我們學(xué)習(xí),相信在大部分業(yè)務(wù)場(chǎng)景中都會(huì)用到,這里cas-server提供了良好的擴(kuò)展性,方便第三方庫(kù)集成。主要還是用到了面向接口編程。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 這篇文章介紹了Mobile BI(移動(dòng)商務(wù)智能)使用過(guò)程中涉及的各種身份認(rèn)證的方式,主要目的是對(duì)這些方式的原理進(jìn)行...
    雨_樹(shù)閱讀 2,292評(píng)論 1 2
  • ticket是Server端與client端通信的票據(jù),有了ticket服務(wù)才知道你是首次請(qǐng)求認(rèn)證還是認(rèn)證通過(guò)來(lái)驗(yàn)...
    a樂(lè)樂(lè)_1234閱讀 13,037評(píng)論 0 1
  • CAS,Central Authentication Service—中央認(rèn)證服務(wù),是Yale 大學(xué)發(fā)起的一個(gè)企業(yè)...
    ackier閱讀 1,722評(píng)論 0 0
  • 作為不愛(ài)做選擇的人,我直接在客戶端把電影那一欄按好評(píng)度排名,選擇了一個(gè)名字清奇的作品,第八日的蟬。跟著并不明快的節(jié)...
    Elly奇閱讀 677評(píng)論 0 0

友情鏈接更多精彩內(nèi)容