CAS 自定义登录逻辑:集成 MySQL 数据库的完整指南 基于 `cas-overlay-template` 的实现

发布于:2025-05-14 ⋅ 阅读:(13) ⋅ 点赞:(0)

1. 准备 MySQL 数据库

首先,确保你有一个 MySQL 数据库,并创建一个用户表(users)用于存储用户名和密码。以下是表结构的示例:

CREATE DATABASE cas_auth;

USE cas_auth;

CREATE TABLE users (
    username VARCHAR(50) NOT NULL PRIMARY KEY,
    password VARCHAR(100) NOT NULL
);

INSERT INTO users (username, password) VALUES ('testUser', 'testPassword');

2. 修改 CustomAuthenticationHandler 以支持 MySQL 数据库

CustomAuthenticationHandler 中,我们需要通过 JDBC 连接到 MySQL 数据库并验证用户凭证。以下是完整的代码实现:

CustomAuthenticationHandler.java
package org.apereo.cas.authentication;

import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.apereo.cas.ticket.registry.TicketRegistrySupport;
import org.apereo.cas.util.crypto.CipherExecutor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * 自定义的 AuthenticationHandler,支持 MySQL 数据库验证。
 */
public class CustomAuthenticationHandler extends AbstractAuthenticationHandler {
    private final JdbcTemplate jdbcTemplate;

    public CustomAuthenticationHandler(
        final String name,
        final ServicesManager servicesManager,
        final PrincipalFactory principalFactory,
        final int order,
        final TicketRegistrySupport ticketRegistrySupport,
        final CipherExecutor<String, String> cipherExecutor) {
        super(name, servicesManager, principalFactory, order, ticketRegistrySupport, cipherExecutor);

        // 配置 MySQL 数据源
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/cas_auth");
        dataSource.setUsername("root"); // 替换为你的数据库用户名
        dataSource.setPassword("password"); // 替换为你的数据库密码

        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    @Override
    protected AuthenticationHandlerExecutionResult doAuthentication(
        final Credential credential) throws GeneralSecurityException, PreventedException {
        final String username = credential.getId();
        final String password = credential.getPassword();

        try {
            // 查询数据库中的用户信息
            final String query = "SELECT password FROM users WHERE username = ?";
            final String dbPassword = jdbcTemplate.queryForObject(query, new Object[]{username}, String.class);

            // 验证密码
            if (dbPassword != null && dbPassword.equals(password)) {
                // 如果验证通过,返回一个 AuthenticationHandlerExecutionResult 对象
                return createHandlerResult(credential, principalFactory.createPrincipal(username), null);
            } else {
                throw new GeneralSecurityException("Invalid credentials");
            }
        } catch (Exception e) {
            throw new GeneralSecurityException("Error during authentication", e);
        }
    }

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

3. 添加 MySQL 依赖

build.gradle 文件中,添加 MySQL JDBC 驱动的依赖项:

dependencies {
    implementation 'mysql:mysql-connector-java:8.0.32'
}

然后运行以下命令以下载依赖项:

./gradlew build

4. 配置自定义的 AuthenticationHandler

src/main/java/org/apereo/cas 目录下,确保你已经创建了 CustomAuthenticationConfiguration.java 文件,并注册了自定义的 AuthenticationHandler

CustomAuthenticationConfiguration.java
package org.apereo.cas;

import org.apereo.cas.authentication.AuthenticationHandlerExecutionResult;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.authentication.principal.PrincipalFactoryUtils;
import org.apereo.cas.services.ServicesManager;
import org.apereo.cas.ticket.registry.TicketRegistrySupport;
import org.apereo.cas.util.crypto.CipherExecutor;
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("customAuthenticationConfiguration")
public class CustomAuthenticationConfiguration {
    @Autowired
    @Qualifier("servicesManager")
    private ServicesManager servicesManager;

    @Autowired
    @Qualifier("defaultPrincipalFactory")
    private PrincipalFactory principalFactory;

    @Autowired
    @Qualifier("ticketRegistrySupport")
    private TicketRegistrySupport ticketRegistrySupport;

    @Autowired
    @Qualifier("passwordEncoder")
    private CipherExecutor<String, String> passwordEncoder;

    @Bean
    public AuthenticationHandler customAuthenticationHandler() {
        return new CustomAuthenticationHandler(
            "CustomAuthenticationHandler",
            servicesManager,
            principalFactory,
            0,
            ticketRegistrySupport,
            passwordEncoder
        );
    }
}

5. 修改 application.yml 配置文件

src/main/resources/application.yml 文件中,添加以下配置以注册自定义的 AuthenticationHandler

cas:
  authn:
    handlers:
      - name: CustomAuthenticationHandler
        class: org.apereo.cas.CustomAuthenticationHandler

6. 重新构建并运行 CAS 服务器

完成上述修改后,重新构建 CAS 项目:

./gradlew clean build

然后运行:

java -jar build/libs/cas.war

7. 测试自定义登录逻辑

访问 https://localhost:8443/cas,输入数据库中存储的用户名和密码(例如 testUsertestPassword),验证是否能够成功登录。

如果登录失败,请检查以下几点:

  • 数据库连接:确保数据库连接信息(用户名、密码、URL)正确无误。
  • 日志信息:查看 CAS 的日志文件,了解登录失败的具体原因。
  • SQL 查询:确保 SQL 查询语句正确,并且数据库中存在对应的用户记录。

8. 总结

通过上述步骤,我们成功地在 cas-overlay-template 项目中实现了基于 MySQL 数据库的自定义登录逻辑。主要步骤包括:

  1. 创建自定义的 AuthenticationHandler,实现具体的认证逻辑。
  2. 通过 Spring 配置类将自定义的 AuthenticationHandler 注入到 CAS 的认证流程中。
  3. 添加 MySQL 依赖并配置数据库连接。
  4. 重新构建并运行 CAS 服务器,测试自定义登录逻辑。

如果你需要进一步扩展功能,例如支持密码加密存储或使用其他数据库,可以在 CustomAuthenticationHandler 中实现相应的逻辑。

希望本文对你有所帮助!如果你有任何问题或建议,欢迎在评论区留言。