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; } }
额外注意事项
- 务必补充数据源的核心配置(驱动类、DB地址、用户名密码等),否则数据源无法正常建立连接。
- 建议根据业务需求配置连接池参数,避免资源过载或浪费。
- 如果需要从配置文件读取数据库参数,可以在
adapter.xml中添加自定义属性,再通过getProperty方法在代码中获取,提升配置灵活性。
这样修改后,既保证了数据源的正确复用,也不会干扰SecurityCheck的状态管理,SSO功能应该就能恢复正常了。
内容的提问来源于stack exchange,提问作者farahm
相关产品推荐
相关产品推荐

