自定义验证原理
AI回答如下:
在 CAS 5.3.2 中,AuthenticationHandler 处理器的调用是由 CAS 的认证流程 控制的。具体来说,AuthenticationHandler 是在 Spring Web Flow 的流程中被调用的。以下是详细的调用流程和关键点:
1. CAS 认证流程概述
CAS 的认证流程是基于 Spring Web Flow 实现的。登录流程的核心逻辑定义在 login-webflow.xml 文件中。以下是认证流程的主要步骤:
-
初始化流程:加载登录页面。
-
绑定凭证:将用户输入的凭证绑定到
Credential对象。 -
验证凭证:调用
AuthenticationHandler验证凭证。 -
生成票据:如果验证成功,生成 Ticket Granting Ticket (TGT)。
-
重定向到服务:将用户重定向回原始服务。
2. AuthenticationHandler 的调用位置
AuthenticationHandler 的调用发生在 realSubmit 节点中。以下是关键代码片段:
login-webflow.xml 中的 realSubmit 节点
-
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 配置文件
-
customAuthenticationHandler:自定义的AuthenticationHandler。 -
PolicyBasedAuthenticationManager:CAS 的默认AuthenticationManager实现。
5. 完整的调用流程
以下是 AuthenticationHandler 的完整调用流程:
-
用户提交登录表单:
-
用户在登录页面输入用户名、密码等信息,并提交表单。
-
-
绑定凭证:
-
CAS 调用
authenticationViaFormAction.doBind,将表单数据绑定到Credential对象。
-
-
验证凭证:
-
CAS 调用
authenticationViaFormAction.submit,触发AuthenticationManager的验证逻辑。 -
AuthenticationManager遍历所有注册的AuthenticationHandler,调用supports方法检查是否支持当前凭证类型。 -
如果支持,调用
authenticate方法验证凭证。
-
-
生成票据:
-
如果验证成功,CAS 生成 Ticket Granting Ticket (TGT)。
-
-
重定向到服务:
-
CAS 将用户重定向回原始服务。
-
6. 关键类和方法
以下是 AuthenticationHandler 调用流程中的关键类和方法:
-
AuthenticationViaFormAction:-
doBind:绑定凭证。 -
submit:触发验证逻辑。
-
-
PolicyBasedAuthenticationManager:-
authenticate:调用AuthenticationHandler验证凭证。
-
-
AuthenticationHandler:-
supports:检查是否支持当前凭证类型。 -
authenticate:验证凭证。
-
-
UsernamePasswordCredential:-
CAS 默认的凭证类型,包含
username和password字段。
-
7. 自定义 AuthenticationHandler 的调用
如果您实现了自定义的 AuthenticationHandler,CAS 会在以下情况下调用它:
-
凭证类型匹配:自定义
AuthenticationHandler的supports方法返回true。 -
验证逻辑:CAS 调用自定义
AuthenticationHandler的authenticate方法验证凭证。
8. 了解
CAS 的 AuthenticationHandler 处理器按照 order 属性的值从小到大依次执行。默认情况下,处理器的顺序如下:
-
AcceptUsersAuthenticationHandler(order=0) -
LdapAuthenticationHandler(order=1) -
QueryDatabaseAuthenticationHandler(order=2) -
RestAuthenticationHandler(order=3) -
SpnegoAuthenticationHandler(order=4) -
X509AuthenticationHandler(order=5) -
JaasAuthenticationHandler(order=6) -
MongoDbAuthenticationHandler(order=7) -
GroovyAuthenticationHandler(order=8) -
FileAuthenticationHandler(order=9) -
OAuth20AuthenticationHandler(order=10) -
OpenIdAuthenticationHandler(order=11) -
RadiusAuthenticationHandler(order=12) -
TrustedAuthenticationHandler(order=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博客

浙公网安备 33010602011771号