H__D  

自定义验证原理

  AI回答如下:

在 CAS 5.3.2 中,AuthenticationHandler 处理器的调用是由 CAS 的认证流程 控制的。具体来说,AuthenticationHandler 是在 Spring Web Flow 的流程中被调用的。以下是详细的调用流程和关键点:


1. CAS 认证流程概述

CAS 的认证流程是基于 Spring Web Flow 实现的。登录流程的核心逻辑定义在 login-webflow.xml 文件中。以下是认证流程的主要步骤:

  1. 初始化流程:加载登录页面。

  2. 绑定凭证:将用户输入的凭证绑定到 Credential 对象。

  3. 验证凭证:调用 AuthenticationHandler 验证凭证。

  4. 生成票据:如果验证成功,生成 Ticket Granting Ticket (TGT)。

  5. 重定向到服务:将用户重定向回原始服务。


2. AuthenticationHandler 的调用位置

AuthenticationHandler 的调用发生在 realSubmit 节点中。以下是关键代码片段:

login-webflow.xml 中的 realSubmit 节点

<action-state id="realSubmit">
    <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credential)" />
    <evaluate expression="authenticationViaFormAction.submit(flowRequestContext, flowScope.credential, messageContext)" />
    <transition to="generateLoginTicket" />
</action-state>
  • authenticationViaFormAction.doBind:将用户输入的凭证绑定到 Credential 对象。

  • authenticationViaFormAction.submit:调用 AuthenticationManager 验证凭证。


3. AuthenticationManager 的调用

  在 authenticationViaFormAction.submit 方法中,CAS 会调用 AuthenticationManager 来验证凭证。AuthenticationManager 会遍历所有注册的 AuthenticationHandler,并调用它们的 authenticate 方法。

AuthenticationManager 的核心逻辑

public AuthenticationHandlerExecutionResult authenticate(Credential credential) throws AuthenticationException {
    for (AuthenticationHandler handler : authenticationHandlers) {
        if (handler.supports(credential)) {
            return handler.authenticate(credential);
        }
    }
    throw new AuthenticationException("No supported authentication handler found");
}

 

  • handler.supports(credential):检查 AuthenticationHandler 是否支持当前凭证类型。

  • handler.authenticate(credential):调用 AuthenticationHandler 的验证逻辑。


4. AuthenticationHandler 的注册

  AuthenticationHandler 是通过 Spring 配置文件注册到 AuthenticationManager 中的。以下是注册 AuthenticationHandler 的示例配置:

Spring 配置文件

<bean id="authenticationManager" class="org.apereo.cas.authentication.PolicyBasedAuthenticationManager">
    <constructor-arg>
        <map>
            <entry key-ref="customAuthenticationHandler" value="#{T(org.apereo.cas.authentication.AuthenticationHandlerExecutionResult).SUCCESS}" />
        </map>
    </constructor-arg>
</bean>
  • customAuthenticationHandler:自定义的 AuthenticationHandler

  • PolicyBasedAuthenticationManager:CAS 的默认 AuthenticationManager 实现。


5. 完整的调用流程

以下是 AuthenticationHandler 的完整调用流程:

  1. 用户提交登录表单

    • 用户在登录页面输入用户名、密码等信息,并提交表单。

  2. 绑定凭证

    • CAS 调用 authenticationViaFormAction.doBind,将表单数据绑定到 Credential 对象。

  3. 验证凭证

    • CAS 调用 authenticationViaFormAction.submit,触发 AuthenticationManager 的验证逻辑。

    • AuthenticationManager 遍历所有注册的 AuthenticationHandler,调用 supports 方法检查是否支持当前凭证类型。

    • 如果支持,调用 authenticate 方法验证凭证。

  4. 生成票据

    • 如果验证成功,CAS 生成 Ticket Granting Ticket (TGT)。

  5. 重定向到服务

    • CAS 将用户重定向回原始服务。


6. 关键类和方法

  以下是 AuthenticationHandler 调用流程中的关键类和方法:

  1. AuthenticationViaFormAction

    • doBind:绑定凭证。

    • submit:触发验证逻辑。

  2. PolicyBasedAuthenticationManager

    • authenticate:调用 AuthenticationHandler 验证凭证。

  3. AuthenticationHandler

    • supports:检查是否支持当前凭证类型。

    • authenticate:验证凭证。

  4. UsernamePasswordCredential

    • CAS 默认的凭证类型,包含 username 和 password 字段。


7. 自定义 AuthenticationHandler 的调用

  如果您实现了自定义的 AuthenticationHandler,CAS 会在以下情况下调用它:

  1. 凭证类型匹配:自定义 AuthenticationHandler 的 supports 方法返回 true

  2. 验证逻辑:CAS 调用自定义 AuthenticationHandler 的 authenticate 方法验证凭证。


8. 了解

  CAS 的 AuthenticationHandler 处理器按照 order 属性的值从小到大依次执行。默认情况下,处理器的顺序如下:

  1. AcceptUsersAuthenticationHandlerorder=0

  2. LdapAuthenticationHandlerorder=1

  3. QueryDatabaseAuthenticationHandlerorder=2

  4. RestAuthenticationHandlerorder=3

  5. SpnegoAuthenticationHandlerorder=4

  6. X509AuthenticationHandlerorder=5

  7. JaasAuthenticationHandlerorder=6

  8. MongoDbAuthenticationHandlerorder=7

  9. GroovyAuthenticationHandlerorder=8

  10. FileAuthenticationHandlerorder=9

  11. OAuth20AuthenticationHandlerorder=10

  12. OpenIdAuthenticationHandlerorder=11

  13. RadiusAuthenticationHandlerorder=12

  14. TrustedAuthenticationHandlerorder=13

  总结

AuthenticationHandler 处理器是在 CAS 的认证流程 中被调用的,具体调用位置是 login-webflow.xml 中的 realSubmit 节点。CAS 通过 AuthenticationManager 遍历所有注册的 AuthenticationHandler,并调用它们的 authenticate 方法验证凭证。通过实现自定义的 AuthenticationHandler,您可以扩展 CAS 的认证逻辑,支持自定义的凭证类型和验证逻辑。

自定义验证

1、引入依赖

<!-- Auth -->
<dependency>
    <groupId>org.apereo.cas</groupId>
    <artifactId>cas-server-core-authentication</artifactId>
    <version>${cas.version}</version>
</dependency>
<dependency>
    <groupId>org.apereo.cas</groupId>
    <artifactId>cas-server-core-authentication-api</artifactId>
    <version>${cas.version}</version>
</dependency>

 

 2、编写AuthenticationHandler 处理器

package com.test.cas.handler;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apereo.cas.authentication.AuthenticationHandlerExecutionResult;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.PreventedException;
import org.apereo.cas.authentication.UsernamePasswordCredential;
import org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.springframework.beans.factory.annotation.Autowired;

import javax.security.auth.login.FailedLoginException;
import java.security.GeneralSecurityException;
import java.util.Collections;

/**
 * 自定义验证器
 */
@Slf4j
public class MyAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {

    @Autowired
    private ObjectMapper objectMapper;

    public MyAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {
        super(name, servicesManager, principalFactory, order);
    }

    @Override
    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential, String originalPassword)
            throws GeneralSecurityException, PreventedException {

        try {
            // 打印凭证信息
            log.info("credential: {}", objectMapper.writeValueAsString(credential));
        } catch (JsonProcessingException e) {

        }
        // 获取用户名
        String username = credential.getUsername();

        // 检查用户名是否为 "admin"
        if ("admin".equals(username)) {
            // 认证成功,返回凭证
            return createHandlerResult(credential, this.principalFactory.createPrincipal(username, Collections.emptyMap()));
        } else {
            // 认证失败,抛出异常
            throw new FailedLoginException("Invalid username: " + username);
        }
    }

    @Override
    public boolean supports(Credential credential) {
        // 仅支持 UsernamePasswordCredential 类型的凭证
        return credential instanceof UsernamePasswordCredential;
    }
}

 3、注册自定义AuthenticationHandler 处理器

package com.test.cas.config;

import com.test.cas.handler.MyAuthenticationHandler;
import org.apereo.cas.authentication.AuthenticationEventExecutionPlan;
import org.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer;
import org.apereo.cas.authentication.AuthenticationHandler;
import org.apereo.cas.authentication.principal.DefaultPrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration("myAuthenticationConfiguration")
public class MyAuthenticationConfiguration implements AuthenticationEventExecutionPlanConfigurer {

    @Autowired
    @Qualifier("servicesManager")
    private ServicesManager servicesManager;

    @Bean
    public AuthenticationHandler adminAuthenticationHandler() {
        return new MyAuthenticationHandler(
                MyAuthenticationHandler.class.getSimpleName(), // 处理器名称
                servicesManager, // ServicesManager
                new DefaultPrincipalFactory(), // PrincipalFactory
                1 // 处理器顺序
        );
    }

    @Override
    public void configureAuthenticationExecutionPlan(AuthenticationEventExecutionPlan plan) {
        // 注册自定义的认证处理器
        plan.registerAuthenticationHandler(adminAuthenticationHandler());
    }
}

4、启动cas-overlay-template项目

  在登录页输入 用户名:admin,密码:随便,即可登录成功,完成验证

 

 

 参考:cas5.3.2单点登录-自定义登录验证(四)_cas 5.3 policybasedauthenticationmanager 使用-CSDN博客

 

posted on 2025-01-19 22:21  H__D  阅读(516)  评论(0)    收藏  举报