You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

apache.commons.dbcp.BasicDataSource为何导致MobileFirst适配器SSO失效?

问题分析与解决方案

你遇到的SSO失效问题,根源在于每次验证凭证时都重新创建BasicDataSource实例,这直接破坏了MobileFirst SecurityCheck的状态管理机制。

为什么会影响SSO?

MobileFirst的UserAuthenticationSecurityCheck实例是被容器复用的,并非每个请求都新建实例。你在validateCredentials方法里每次执行dataSource = new BasicDataSource();,会覆盖类的成员变量,干扰SecurityCheck内部维护的用户会话关联状态——而SSO正是依赖这些状态来识别已登录用户的。另外,频繁创建数据源连接池也是非常低效的做法,会造成不必要的资源消耗。

修复方案

把数据源的初始化逻辑移到类的初始化阶段,比如使用@PostConstruct注解的方法,确保只初始化一次:

修改后的UserLogin.java代码:

package com.sample;
import com.ibm.mfp.security.checks.base.UserAuthenticationSecurityCheck;
import com.ibm.mfp.server.registration.external.model.AuthenticatedUser;
import org.apache.commons.dbcp.BasicDataSource;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.sql.*;

public class UserLogin extends UserAuthenticationSecurityCheck {
    private String userId, displayName;
    private String errorMsg;
    private boolean rememberMe = false;
    public BasicDataSource dataSource = null;

    // 初始化数据源,仅在实例创建时执行一次
    @PostConstruct
    public void initDataSource() {
        dataSource = new BasicDataSource();
        // 补充你的数据源配置信息
        // dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        // dataSource.setUrl("jdbc:mysql://your-db-host:3306/your-db-name");
        // dataSource.setUsername("db-username");
        // dataSource.setPassword("db-password");
        // 可按需配置连接池参数,比如最大连接数、空闲超时等
        // dataSource.setMaxActive(10);
    }

    @Override
    protected AuthenticatedUser createUser() {
        return new AuthenticatedUser(userId, displayName, this.getName());
    }

    @Override
    protected boolean validateCredentials(Map<String, Object> credentials) {
        if(credentials!=null && credentials.containsKey("username") && credentials.containsKey("password")){
            String username = credentials.get("username").toString();
            String password = credentials.get("password").toString();
            
            // 移除这里的dataSource = new BasicDataSource();
            if(!username.isEmpty() && !password.isEmpty() && username.equals(password)) {
                userId = username;
                displayName = username;
                //Optional RememberMe
                if(credentials.containsKey("rememberMe") ){
                    rememberMe = Boolean.valueOf(credentials.get("rememberMe").toString());
                }
                errorMsg = null;
                return true;
            } else {
                errorMsg = "Wrong Credentials";
            }
        } else{
            errorMsg = "Credentials not set properly";
        }
        return false;
    }

    @Override
    protected Map<String, Object> createChallenge() {
        Map challenge = new HashMap();
        challenge.put("errorMsg",errorMsg);
        challenge.put("remainingAttempts",getRemainingAttempts());
        return challenge;
    }

    @Override
    protected boolean rememberCreatedUser() {
        return rememberMe;
    }
}

额外注意事项

  1. 务必补充数据源的核心配置(驱动类、DB地址、用户名密码等),否则数据源无法正常建立连接。
  2. 建议根据业务需求配置连接池参数,避免资源过载或浪费。
  3. 如果需要从配置文件读取数据库参数,可以在adapter.xml中添加自定义属性,再通过getProperty方法在代码中获取,提升配置灵活性。

这样修改后,既保证了数据源的正确复用,也不会干扰SecurityCheck的状态管理,SSO功能应该就能恢复正常了。

内容的提问来源于stack exchange,提问作者farahm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:21:46