Spring-Security saml2:如何获取当前用户? [英] spring-security saml2 : How to obtain the current user?

查看:10
本文介绍了Spring-Security saml2:如何获取当前用户?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用5.2.0.RELEASE版本的Spring-Security和Spring-Security-saml2-service-Provider。我尝试在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响应(authation.getSaml2Response),但我不确定如何获得带有用户ID的断言。

真的,我想从href="https://stackoverflow.com/questions/31099829/retrieve-attributes-and-nameid-from-a-saml-response-xml">Retrieve响应(Xml)中获取一个SAML属性和名称ID 在Java代码中。不确定Spring中是否有什么东西可以帮助我--安全。

更新 因此,在做了一些工作之后,我使用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使用Subject元素中的NameID值来设置‘UserName’。如果为‘Temporent NameID Format’,则对于每个SAML规范的每个SSO流,该值必须是不同的/唯一的。

您可以实现自己的UserDetailsServiceorg.springframework.security.saml.userdetails.SAMLUserDetailsService在方法loadUserBySAML中实现org.springframework.security.saml.userdetails.SAMLUserDetailsService可以提取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;
}

这篇关于Spring-Security saml2:如何获取当前用户?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆