首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >spring安全saml2 :如何获得当前用户?

spring安全saml2 :如何获得当前用户?
EN

Stack Overflow用户
提问于 2019-10-15 18:22:14
回答 1查看 4.3K关注 0票数 4

我正在使用版本为5.2.0.RELEASE的spring-security和spring-security-saml2 2服务提供者,在IDP认证之后,我尝试获取当前断言,以便将其映射到本地系统中的用户。我使用这段代码获取Saml2Authentication对象

代码语言:javascript
复制
@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获得断言。

真的,我想在Java中做Retrieve Attributes and NameID from a SAML Response (XML) 。不知道春天的保安有什么能帮我的。

更新--在做了一些工作之后,我使用OpenSAML库获得属性,并解析SAMLv2响应。我不知道这是不是正确的方法

代码语言:javascript
复制
@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();
    }
EN

回答 1

Stack Overflow用户

发布于 2019-10-17 07:10:22

默认情况下,使用Subject元素中的NameID值来设置“用户名”。如果是“瞬态NameID格式”,则对于每个SAML规范中的每个SSO流,其值必须是不同的/唯一的。

您可以实现自己的UserDetailsService (在方法loadUserBySAML中实现org.springframework.security.saml.userdetails.SAMLUserDetailsService ),您可以提取SAML属性

代码语言:javascript
复制
@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;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58400571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档