H__D  

  本例使用的cas源码是 7.3.0-SNAPSHOT

页面控制

页面:

登录页:E:\git-repository\cas-server\support\cas-server-support-thymeleaf\src\main\resources\templates\login
E:\git-repository\cas-server\support\cas-server-support-thymeleaf\src\main\resources\templates\fragments\loginform.html

中文资源:
E:\git-repository\cas-server\support\cas-server-support-thymeleaf\src\main\resources\messages_zh_CN.properties


登录错误页:E:\git-repository\cas-server\support\cas-server-support-thymeleaf\src\main\resources\templates\login-error
注销页:E:\git-repository\cas-server\support\cas-server-support-thymeleaf\src\main\resources\templates\logout


webflow配置

Wefflow上下文配置类

E:\git-repository\cas-server\core\cas-server-core-webflow\src\main\java\org\apereo\cas\config\CasWebflowContextConfiguration.java

默认登录Webflow配置类(主要内容在这里)

CAS登录流程的核心配置类
E:\git-repository\cas-server\core\cas-server-core-webflow-api\src\main\java\org\apereo\cas\web\flow\configurer\DefaultLoginWebflowConfigurer.java


在CAS登录流程中,当登录表单提交后,系统会通过以下调用链处理认证请求:

1. 表单提交触发转移
在 createLoginFormView 方法中定义的转移规则生效:
createTransitionForState(state, CasWebflowConstants.TRANSITION_ID_SUBMIT, CasWebflowConstants.STATE_ID_REAL_SUBMIT);

2. 核心处理方法
realSubmit 状态对应的处理方法是:
protected void createRealSubmitAction(final Flow flow) {
val state = createActionState(flow, CasWebflowConstants.STATE_ID_REAL_SUBMIT,
CasWebflowConstants.ACTION_ID_AUTHENTICATION_VIA_FORM_ACTION);
// 转移配置...
}
关键处理类:
AuthenticationViaFormAction (对应 ACTION_ID_AUTHENTICATION_VIA_FORM_ACTION)


3. 认证处理调用链
表单提交后的完整处理流程:AuthenticationViaFormAction.doExecute()
AuthenticationViaFormAction(在support/cas-server-support-actions/src/main/java/org/apereo/cas/config/CasSupportActionsAutoConfiguration.java定义)
实际上是交给core/cas-server-core-webflow-api/src/main/java/org/apereo/cas/web/flow/actions/InitialAuthenticationAction.java 处理

// 处理:E:\git-repository\cas-server\core\cas-server-core-webflow-api\src\main\java\org\apereo\cas\web\flow\actions\AbstractAuthenticationAction.java

=======>doExecuteInternal()方法

1.自适应策略检查
2.先尝试服务票据解析(可能已有有效会话)
3.需要完整认证时,返回认证成功或失败事件 initialAuthenticationAttemptWebflowEventResolver.resolveSingle(requestContext);
4.事件钩子机制

=======>resolveSingle(requestContext);

1、凭证提取:从请求上下文中获取UsernamePasswordCredential等凭证对象
2、认证委托:调用AuthenticationManager.authenticate()
3、结果转换:将认证结果映射为Webflow事件

=======>DefaultAuthenticationManager.authenticateInternal()

地址:E:\git-repository\cas-server\core\cas-server-core-authentication-api\src\main\java\org\apereo\cas\authentication\DefaultAuthenticationManager.java

1、根据事务特征(如服务URL)获取适用的认证处理器
2、双重循环认证

 

protected AuthenticationBuilder authenticateInternal(final AuthenticationTransaction transaction) throws Throwable {
        val credentials = transaction.getCredentials();
        LOGGER.debug("Authentication credentials provided for this transaction are [{}]", credentials);
        // 空凭证检查
        if (credentials.isEmpty()) {
            LOGGER.error("Resolved authentication handlers for this transaction are empty");
            throw new AuthenticationException("Resolved credentials for this transaction are empty");
        }
        // 构建认证结果容器
        val authenticationBuilder = new DefaultAuthenticationBuilder(NullPrincipal.getInstance());
        credentials.forEach(authenticationBuilder::addCredential);
        // 根据事务特征(如服务URL)获取适用的认证处理器
        // 典型处理器:
        // LdapAuthenticationHandler(LDAP认证)
        // JdbcAuthenticationHandler(数据库认证)
        // X509AuthenticationHandler(证书认证)
        val handlerSet = authenticationEventExecutionPlan.resolveAuthenticationHandlers(transaction);
        LOGGER.debug("Candidate resolved authentication handlers for this transaction are [{}]", handlerSet);

        try {
            // 双重循环认证
            // 凭证级循环
            for (val credential : credentials) {
                LOGGER.debug("Attempting to authenticate credential [{}]", credential);
                // 处理器级循环
                val itHandlers = handlerSet.iterator();
                var proceedWithNextHandler = true;
                while (proceedWithNextHandler && itHandlers.hasNext()) {
                    val handler = itHandlers.next();
                    if (handler.supports(credential)) {
                        try {
                            val resolver = getPrincipalResolverLinkedToHandlerIfAny(handler, transaction);
                            LOGGER.debug("Attempting authentication of [{}] using [{}]", credential.getId(), handler.getName());

                            // 认证执行核心
                            // 凭证验证:调用 handler.authenticate(credential)
                            // 主体解析:通过 PrincipalResolver 转换认证结果
                            // 结果收集:将成功/失败证据存入 authenticationBuilder
                            authenticateAndResolvePrincipal(authenticationBuilder, credential, resolver, handler, transaction.getService());

                            val authnResult = authenticationBuilder.build();
                            val executionResult = evaluateAuthenticationPolicies(authnResult, transaction, handlerSet);
                            proceedWithNextHandler = !executionResult.isSuccess();
                        } catch (final GeneralSecurityException e) {
                            handleAuthenticationException(e, handler.getName(), authenticationBuilder);
                            proceedWithNextHandler = shouldAuthenticationChainProceedOnFailure(transaction, e);
                        } catch (final Exception e) {
                            LOGGER.error("Authentication has failed. Credentials may be incorrect or CAS cannot "
                                + "find authentication handler that supports [{}] of type [{}]. Examine the configuration to "
                                + "ensure a method of authentication is defined and analyze CAS logs at DEBUG level to trace "
                                + "the authentication event.", credential, credential.getClass().getSimpleName());

                            handleAuthenticationException(e, handler.getName(), authenticationBuilder);
                            proceedWithNextHandler = shouldAuthenticationChainProceedOnFailure(transaction, e);
                        }
                    } else {
                        LOGGER.debug("Authentication handler [{}] does not support the credential type [{}].",
                            handler.getName(), credential);
                    }
                }
            }
            // 策略评估
            evaluateFinalAuthentication(authenticationBuilder, transaction, handlerSet);
            return authenticationBuilder;
        } finally {
            for (val handler : handlerSet) {
                if (handler.isDisposable() && handler instanceof final DisposableBean db) {
                    db.destroy();
                }
            }
        }
    }

 

=======>QueryDatabaseAuthenticationHandler.authenticateUsernamePasswordInternal()

E:\git-repository\cas-server\support\cas-server-support-jdbc-authentication\src\main\java\org\apereo\cas\jdbc\QueryDatabaseAuthenticationHandler.java

1. 凭证提取
2. 数据库查询
3. 密码验证策略
4. 账户状态检查
5. 主体构建

posted on 2025-07-06 18:11  H__D  阅读(47)  评论(0)    收藏  举报