5

I have been digging into spring security yaml a little bit yesterday to make it work with Okta SAML. Logging in works, but the response XML contains user attributes that apparently cannot be extracted automatically into an attribute map. The response contains a fields like this

<saml2:Attribute Name="user.lastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
  <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">
    Surname
  </saml2:AttributeValue>
</saml2:Attribute>

Once an authentication is successful, I would like to put those in the authentication information. When logging in via github/oauth, the OAuth2AuthenticatedPrincipal class has an attributes map, however the Saml2AuthenticatedPrincipal only features a name.

What would be the correct way to solve this?

Right now I am thinking of a custom AuthenticationSuccessHandler that populates a custom Saml2AuthenticatedPrincipalWithAttributes class which contains all the attributes by parsing the provided XML response (via .getDetails()) a second time (or put them into the session).

I have a hunch that this is probably not the spring way to do things and would love to get a second opinion. When googling around you mainly find examples of spring security saml, before it got merged into spring security, which seems to handle things a little bit different, as the mentioned classes do not exist anymore.

Thanks for helping everyone!

alr
  • 1,744
  • 1
  • 10
  • 11
  • having the same question... this guy decided to parse the response manually https://stackoverflow.com/q/58400571/10479742 interestingly that's how OpenSamlAuthenticationProvider parses and validates the response, and then throws away the Assertion. please share the approach that you choose – kostic017 Jun 08 '20 at 08:36
  • So far I did what I mentioned above in my post, as the `UserDetailsService` mentioned in that post was only available in an older version. This also parses the response manually and enriches an attribute map. Then I am setting a new `SecurityContext` that contains the `Principal` with the attribute map. – alr Jun 08 '20 at 12:19
  • ok. btw i was referring to the update in the mentioned question where he also decided to parse the response on his own. i've opened a GitHub issue asking for enhancement/clarifications https://github.com/spring-projects/spring-security/issues/8661 – kostic017 Jun 08 '20 at 12:33
  • 1
    PR https://github.com/spring-projects/spring-security/pull/8667 – kostic017 Jun 09 '20 at 13:22

1 Answers1

4

In the next release of Spring Security (5.4.0) you should be able to do something like this:

@GetMapping("/")
public String index(Model model,
    @AuthenticationPrincipal Saml2AuthenticatedPrincipal principal) {
    String emailAddress = principal.getFirstAttribute("emailAddress");
    model.addAttribute("emailAddress", emailAddress);
    model.addAttribute("userAttributes", principal.getAttributes());
    return "index";
}

For now, I don't know a better workaround than yours.

kostic017
  • 356
  • 3
  • 12
  • i want to add redirect and send the some values in header to redirect url ...any suggestions please – Sriram G Feb 02 '22 at 09:41