基于 SAML sp 的身份验证具有以下简短的工作流程。
- 用户想要在 sp 访问应用程序。
- sp 向 idp 发送 SAMLRequest 令牌。
- idp 使用它并生成 SAMLResponse 令牌。
- idp 将此 SAMLResponse 令牌发送到 sp 给定的 AC-URL。
我的问题是 sp 如何使用这个 SAMLResponse 令牌。逻辑是什么?如果我能得到一些 JAVA 代码帮助,那将是有益的。
基于 SAML sp 的身份验证具有以下简短的工作流程。
我的问题是 sp 如何使用这个 SAMLResponse 令牌。逻辑是什么?如果我能得到一些 JAVA 代码帮助,那将是有益的。
下一个食谱对我有用:
获取 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;
解析生成的 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<LogoutRequest, ?, ?> messageContext = new BasicSAMLMessageContext<LogoutRequest, SAMLObject, SAMLObject>();
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 中包含一些库!!!
这是我在Java中的做法。我使用 XMLBeans 解析 SAMLResponse,然后对其进行解密(如果已加密),然后验证签名:
要求代码有点多,但基本处理是 SP 验证 SAMLResponse,包括格式正确、所需值的存在、正确的协议以及任何其他特定于 SP 的验证(时间限制、数据对应等)。 ),将令牌中标识的用户映射到 SP 上的用户(可能涉及创建用户),并将用户转移到请求的资源。