我正在使用 spring-security 和 spring-security-saml2-service-provider 版本 5.2.0.RELEASE。我正在尝试在 IDP 身份验证后获取当前断言,以便将其映射到本地系统中的用户。
我使用此代码来获取 Saml2Authentication 对象
@Component
@Log4j
public class EventListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {
@Override
public void onApplicationEvent(InteractiveAuthenticationSuccessEvent interactiveAuthenticationSuccessEvent) {
Object principal = interactiveAuthenticationSuccessEvent.getAuthentication().getPrincipal();
Saml2Authentication authentication = (Saml2Authentication)interactiveAuthenticationSuccessEvent.getAuthentication()
但我无法获取用户。我可以获得 saml2 响应 (authentication.getSaml2Response),但我不确定如何使用用户 id 获取断言。
真的,我想做从 SAML 响应 (XML) 检索属性和 NameID https://stackoverflow.com/questions/31099829/retrieve-attributes-and-nameid-from-a-saml-response-xml在Java代码中。不确定 spring-security 中是否有什么东西可以帮助我。
Update经过一些工作后,我使用 OpenSAML 库并解析 SAMLv2 响应来获取属性。我不知道这是否是正确的方法
@Override
public void onApplicationEvent(InteractiveAuthenticationSuccessEvent interactiveAuthenticationSuccessEvent) {
Saml2Authentication authentication = (Saml2Authentication) interactiveAuthenticationSuccessEvent.getAuthentication();
try {
Document messageDoc;
BasicParserPool basicParserPool = new BasicParserPool();
basicParserPool.initialize();
InputStream inputStream = new ByteArrayInputStream(authentication.getSaml2Response().getBytes());
messageDoc = basicParserPool.parse(inputStream);
Element messageElem = messageDoc.getDocumentElement();
Unmarshaller unmarshaller = XMLObjectProviderRegistrySupport.getUnmarshallerFactory().getUnmarshaller(messageElem);
XMLObject samlObject = unmarshaller.unmarshall(messageElem);
Response response = (Response) samlObject;
response.getAssertions().forEach(assertion -> {
assertion.getAttributeStatements().forEach(attributeStatement ->
{
attributeStatement.getAttributes().forEach(attribute -> {
log.error("Names:" + attribute.getName() + getAttributesList(attribute.getAttributeValues()));
});
});
});
} catch (Exception e) {
log.error(e);
}
}
private List<String> getAttributesList(Collection<XMLObject> collection) {
return collection.stream().map(this::getAttributeValue)
.collect(Collectors.toList());
}
private String getAttributeValue(XMLObject attributeValue) {
return attributeValue == null ?
null :
attributeValue instanceof XSString ?
getStringAttributeValue((XSString) attributeValue) :
attributeValue instanceof XSAnyImpl ?
getAnyAttributeValue((XSAnyImpl) attributeValue) :
attributeValue.toString();
}
private String getStringAttributeValue(XSString attributeValue) {
return attributeValue.getValue();
}
private String getAnyAttributeValue(XSAnyImpl attributeValue) {
return attributeValue.getTextContent();
}
默认情况下,Spring SAML Security 使用主题元素中的 NameID 值来设置“用户名”。如果“瞬态 NameID 格式”,则根据 SAML 规范,对于每个 SSO 流,该值必须是不同/唯一的。
您可以自己实现UserDetailsService
它实现了org.springframework.security.saml.userdetails.SAMLUserDetailsService
在方法中loadUserBySAML
您可以提取 SAML 属性
@Override
public Object loadUserBySAML(SAMLCredential credential) throws UsernameNotFoundException {
final List<Attribute> attributesFromAttributeStatement = credential.getAttributes();
final String userName = getUserNameValueFromAttribute(attributesFromAttributeStatement);
// if needed calculate authorities
final List<GrantedAuthority> grantedAuthorities = getGrantedAuthorities();
final User authenticatedUser = new User(userName, "", grantedAuthorities);
return authenticatedUser;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)