免责声明:这并不容易,我还没有测试过。我刚刚反编译了 SAML 身份验证处理程序并检查了那里发生了什么。
您应该知道自己在做什么,并且应该尽量让它坚如磐石。一般来说,在 AEM 中使用围绕身份验证的 API 非常麻烦。
我认为您无法从“标准”SAML 令牌中获取部门等信息。但让我们假设这是令牌有效负载的一部分。
您必须将这些信息存储在某个地方。可能是用户个人资料(例如/home/users/a/<userid>/profile)。
我认为org.apache.sling.auth.core.spi.AuthenticationFeedbackHandler 可以做到这一点。该处理程序将有权访问用户的请求、响应和身份验证信息。所以你必须实现这样一个处理程序,然后在用户认证后调用。
身份验证信息基本上只是一个包含具有相关信息的密钥的映射。一个这样的密钥应该是user.jcr.credentials。对于 SAML,这应该是 com.adobe.granite.auth.saml.extidp.SamlCredentials 的一个实例。
这些凭据包含您可以通过getAttribute() 阅读的“属性”。包含“原始 SAML 响应”的属性称为 samlResponse。所以这应该给你你正在寻找的东西:
private String getSamlResponse(final AuthenticationInfo authenticationInfo) {
if (authenticationInfo == null) {
return "";
}
Object credentialsObject = authenticationInfo.get("user.jcr.credentials");
if (credentialsObject == null) {
return "";
}
try {
SamlCredentials credentials = (SamlCredentials) credentialsObject;
String encryptedSamlResponse = credentials.getAttribute("samlResponse");
if (encryptedSamlResponse == null || encryptedSamlResponse.trim().length() == 0) {
return "";
}
return decryptSamlResponse(encryptedSamlResponse);
} catch (ClassCastException e) {
// Unable to cast "credentialsObject" to "SamlCredentials"
return "";
}
}
注意:
- 以上代码使用
SamlCredentials。 com.adobe.granite.auth.saml 捆绑包不会公开导出此类。您必须反编译该包并将该类复制并粘贴到您自己的包中。
- 您必须使用CryptoSupport 实现
decryptSamlResponse 方法。
如果 SAML 令牌不包含您要查找的信息,您可以尝试使用用户的电子邮件地址来查询某种包含该信息的外部数据库,然后将其存储在用户配置文件中。
无论您做什么,如果您在一个发布者上执行此操作并且您有多个发布者(您通常应该有),那么您还必须考虑在这些发布者之间同步用户配置文件或使用粘性连接。据我所知,同步有点问题,并且有一些问题,您可能会遇到以下情况:第一个请求发送给发布者 1,下一个请求(不久之后)发送给尚未同步配置文件的发布者 2 .使用粘性连接可能会更好。