当前位置: 首页 > 知识库问答 >
问题:

spring security saml2:如何获取当前用户?

魏襦宗
2023-03-14

我正在使用5.2.0版本的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响应(authentication.getSaml2Response),但我不确定如何获得带有用户id的断言。

实际上,我想从Java代码中的SAML响应(XML)中检索属性和名称ID。不确定spring security是否有什么可以帮我的。

更新所以经过一些工作,我使用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();
    }

共有1个答案

子车宏浚
2023-03-14

默认情况下,Spring SAML安全性使用Subject元素中的NameID值来设置“username”。如果是“transient NameID format”,则根据SAML规范,每个SSO流的值必须不同/唯一。

您可以实现自己的UserDetailsService,它实现了org。springframework。安全山姆。用户详细信息。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;
}
 类似资料:
  • 当前文档只讨论获取路由参数,而不是实际的路由段。 例如,如果我想找到当前路由的父级,怎么可能?

  • 我正在访问在woocommerce上显示我的产品(与woocommerce中的正常流程类似)。 在存档产品页面上。php我已经添加了侧边栏和我的商店拥有的所有产品类别(有或没有产品)。我使用了以下代码来执行此操作: 现在页面的左侧有上面的侧边栏,右侧有产品。在每个产品类别中,我都添加了一个带有html格式的小说明,我希望在用户单击该类别时显示该说明。根据woocommerce,当您进入特定类别时(

  • 问题内容: 我想知道如何在JavaScript中将当前用户的名称作为HTML文档的一部分。 在Java中,可以键入以实现此目的。JavaScript的替代方法是什么? 问题答案: JavaScript在当前HTML文档的上下文中运行,因此,除非它在当前页面中,否则您将无法确定有关当前用户的任何信息,或者您对服务器端脚本进行AJAX调用以获取更多信息。 JavaScript将无法确定您的Window

  • 我使用selenium获取网页,并发送kenword获取新页面。但是我怎样才能获得新的网页,并搜索我需要的信息呢 请原谅我没有使用降价。我的问题是:我想在搜索关键词后获得网页,但我编写了浏览器。page_源码,它是百度的主页

  • nuxt3如何在服务端获取当前域名,服务端无法使用location去获取 使用useRequestHeaders获取的空对象