使用SAMLResponse令牌

基于SAML sp的身份validation具有以下简短的工作流程

  • 用户想要在sp访问应用程序。
  • sp将SAMLRequest令牌发送到idp。
  • idp使用它并生成SAMLResponse令牌。
  • idp将此SAMLResponse令牌发送到sp给出的AC-URL。

我的问题是sp如何使用此SAMLResponse令牌。 逻辑是什么? 如果我能获得一些JAVA代码帮助它将是有益的。

下一个食谱对我有用:

  1. 获取SAMLResponse令牌并解码并膨胀:

    // Base64 decode Base64 base64Decoder = new Base64(); byte[] xmlBytes = encodedXmlString.getBytes("UTF-8"); byte[] base64DecodedByteArray = base64Decoder.decode(xmlBytes); // Inflate (uncompress) the AuthnRequest data // First attempt to unzip the byte array according to DEFLATE (rfc 1951) Inflater inflater = new Inflater(true); inflater.setInput(base64DecodedByteArray); // since we are decompressing, it's impossible to know how much space we // might need; hopefully this number is suitably big byte[] xmlMessageBytes = new byte[5000]; int resultLength = inflater.inflate(xmlMessageBytes); if (!inflater.finished()) { throw new RuntimeException("didn't allocate enough space to hold " + "decompressed data"); } inflater.end(); String decodedResponse = new String(xmlMessageBytes, 0, resultLength, "UTF-8"); return decodedResponse; 
  2. 解析生成的XML。 在这里,您可以获得所需的信息,例如,使用它创建POJO (这是用于解析LogoutRequest的示例代码,但与响应类似):

     // Parse the XML. SAX approach, we just need the ID attribute SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); // If we want to validate the doc we need to load the DTD // saxParserFactory.setValidating(true); // Get a SAXParser instance SAXParser saxParser = saxParserFactory.newSAXParser(); // Parse it XMLhandler xmLhandler = new XMLhandler(); saxParser.parse(new ByteArrayInputStream(xmlLogoutRequest.getBytes()), xmLhandler); // Return the SamlVO return xmLhandler.getSamlVO(); 

对于我的用例,我只对几个元素感兴趣,所以我使用SAX

 public class XMLhandler extends DefaultHandler { private SamlVO samlVO; public XMLhandler() { samlVO = new SamlVO(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // Managing a LogoutRequest means that we are going to build a LogoutResponse if (qName.equals("samlp:LogoutRequest")) { // The ID value of a request will be the LogoutResponse's InReponseTo attribute samlVO.setInResponseTo(attributes.getValue("ID")); // From the destination we can get the Issuer element String destination = attributes.getValue("Destination"); if (destination != null) { URL destinationUrl = null; try { destinationUrl = new URL(destination); } catch (MalformedURLException e) { // TODO: We could set the server hostname (take it from a property), but this URL SHOULD be well formed! e.printStackTrace(); } samlVO.setIssuer(destinationUrl.getHost()); } } } public SamlVO getSamlVO() { return samlVO; } } 

希望能帮助到你,

路易斯

PS:你也可以使用像OpenSAML这样的库

 DefaultBootstrap.bootstrap(); HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder(new BasicParserPool()); BasicSAMLMessageContext messageContext = new BasicSAMLMessageContext(); messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request)); decode.decode(messageContext); XMLObjectBuilderFactory builderFactory = org.opensaml.Configuration.getBuilderFactory(); LogoutRequestBuilder logoutRequestBuilder = (LogoutRequestBuilder) builderFactory.getBuilder(LogoutRequest.DEFAULT_ELEMENT_NAME); LogoutRequest logoutRequest = logoutRequestBuilder.buildObject(); logoutRequest = (LogoutRequest) messageContext.getInboundMessage(); 

但是要准备好在CLASSPATH中包含一些库!

询问代码有点多,但基本处理是SPvalidationSAMLResponse,包括良好格式,所需值的存在,正确的协议以及任何其他SP特定的validation(时间约束,数据通信等)。 ),将在令牌中标识的用户映射到SP上的用户(可能涉及创建用户),并将用户转移到所请求的资源。

这是我在Java中的表现。 我使用XMLBeans来解析SAMLResponse,然后对其进行解密(如果它已加密),然后validation签名:

WebBrowserSSOAuthConsumerService