single-sign-on - 登录时未写入 JSESSIONIDSSO cookie
问题描述
我目前有许多应用程序在 Wildfly 10 上运行,并使用带有 SSO 的 Picketbox 安全系统。我目前正在升级到 Wildfly 17 并已将安全配置转换为使用 Elytron 子系统,但在写入 SSO cookie 时遇到问题。我没有升级到 JEE8 安全 API。
正在迁移的应用程序之一(“app1”)非常简单,通过login-config
. web.xml
此应用程序正常工作:我获得了登录表单,提交了我的凭据,并且响应包括 JSESSIONIDSSO cookie。第二个应用程序(“app2”)的实现方式略有不同。它也使用login-config
,但登录页面提交给自定义 servlet,该 servlet 以编程方式使用HttpServletRequest.login(username, password)
. 当我在此应用程序中提交我的凭据时,它们已正确验证,但没有写入 JSESSIONIDSSO cookie。
Wildfly 配置
(它最初是为 AD 设置的,但临时设置为从文件中读取用户以进行更简单的测试)
<subsystem ...>
...
<application-security-domains>
<application-security-domain name="active-directory" http-authentication-factory="ad-http-auth">
<single-sign-on domain="localhost" key-store="sso-ad-keystore" key-alias="localhost">
<credential-reference clear-text="ssopass"/>
</single-sign-on>
</application-security-domain>
</application-security-domains>
</subsystem>
<subsystem xmlns="urn:wildfly:elytron:7.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
<security-domains>
...
<security-domain name="LocalFileDomain" default-realm="LocalFileRealm" permission-mapper="default-permission-mapper">
<realm name="LocalFileRealm"/>
</security-domain>
</security-domains>
<security-realms>
...
<filesystem-realm name="LocalFileRealm">
<file path="fs-realm-users" relative-to="jboss.server.config.dir"/>
</filesystem-realm>
</security-realms>
<http>
...
<http-authentication-factory name="ad-http-auth" security-domain="LocalFileDomain" http-server-mechanism-factory="global">
<mechanism-configuration>
<mechanism mechanism-name="FORM">
<mechanism-realm realm-name="active-directory"/>
</mechanism>
<mechanism mechanism-name="BASIC">
<mechanism-realm realm-name="active-directory"/>
</mechanism>
</mechanism-configuration>
</http-authentication-factory>
<provider-http-server-mechanism-factory name="global"/>
</http>
</subsystem>
应用程序1
<login-config>
<auth-method>BASIC?silent=true,FORM</auth-method>
<realm-name>App Realm</realm-name>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/noAccess.html</form-error-page>
</form-login-config>
</login-config>
<form action="j_security_check" method="post">
Username: <input name="j_username" type="text"/>
Password: <input name="j_password" type="password"/>
<input type="submit"/>
</form>
应用程序2
<login-config>
<auth-method>BASIC?silent=true,FORM</auth-method>
<realm-name>App Realm</realm-name>
<form-login-config>
<form-login-page>/login</form-login-page>
<form-error-page>/login</form-error-page>
</form-login-config>
</login-config>
登录表单使用 Angular 发布到登录 servlet,如下所示:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
if (req.getUserPrincipal() == null) {
String username = req.getParameter(USERNAME_FIELD);
String password = req.getParameter(PASSWORD_FIELD);
if (username == null || password == null) {
setResponseStatusAndOutput(LoginResultStatus.UNAUTHORISED, resp);
return;
}
try {
Person person = this.personRepository.findByLogin(username);
if (person != null) {
req.login(username, password);
req.authenticate(resp); // I've tried with and without this line
setResponseStatusAndOutput(LoginResultStatus.SUCCESS, resp);
} else {
setResponseStatusAndOutput(LoginResultStatus.UNAUTHORISED, resp);
}
} catch (ServletException ex) {
setResponseStatusAndOutput(LoginResultStatus.UNAUTHORISED, resp);
}
} else {
setResponseStatusAndOutput(LoginResultStatus.SUCCESS, resp);
}
}
private void setResponseStatusAndOutput(LoginResultStatus loginResultStatus, HttpServletResponse response) throws IOException {
response.setContentType("application/json");
response.setStatus(loginResultStatus.getCode());
response.getOutputStream().print(String.format("{ \"status\": \"%s\" }", loginResultStatus.getValue()));
}
Undertow 是否不会将 SSO 内容应用于以这种方式进行身份验证的请求,可能是因为我错过了过滤器链中设置它的位置?还是我做错了什么?
编辑 1: 我进行了更多测试以尝试缩小问题范围。
Wildfly 17 Elytron,发布到j_security_check
:登录 OK,写入 JSESSIONIDSSO cookie。
Wildfly 17 Elytron,发布到自定义登录 servlet:登录正常,不写入 JSESSIONIDSSO cookie。
Wildfly 10 Legacy,发布到j_security_check
:登录 OK,写入 JSESSIONIDSSO cookie。
Wildfly 10 Legacy,发布到自定义登录 servlet:登录 OK,写入 JSESSIONIDSSO cookie。
我创建了一个测试项目来演示这一点,其中包括 Wildfly 10 和 17 的配置文件。
解决方案
推荐阅读
- ionic-framework - ionic 4 离子网格不会居中/
- python - 使用行值函数的flask-sqlalchemy查询
- google-cloud-run - 如何获取或生成 Google Cloud Run 服务的部署 URL
- mysql - 在 MySQL 中查找多个数据库中的重复值
- sql - 在 firebase -> bigquery 中计算队列数据,但我想通过跟踪源将它们分开。分组行不通?
- java - 有没有办法通过 Java 6 支持 opencmis 1.1 以连接到 Alfresco CMS?
- python-3.6 - 命令出错,退出状态为 1:python setup.py egg_info
- javascript - React Native 0.59.9 应用程序在 android 中崩溃
- html - 为什么是这样包含以前的 div?
- ios - Instantiateviewcontrollerwithidenfier 在 Apple 上找不到故事板