11

SAML sp ベースの認証には、次の短いワークフローがあります。

  • ユーザーは sp でアプリケーションにアクセスしたいと考えています。
  • sp は SAMLRequest トークンを idp に送信します。
  • idp はそれを消費し、SAMLResponse トークンを生成します。
  • idp は、この SAMLResponse トークンを、sp によって指定された AC-URL に送信します。

私の質問は、sp がこの SAMLResponse トークンをどのように消費するかです。ロジックは何ですか?JAVA コードのヘルプを得ることができれば、それは有益です。

4

3 に答える 3

16

次のレシピは私のために働いています:

  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<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 に含める準備をしてください!!!

于 2012-01-31T14:08:54.550 に答える
2

これが私がJavaで行う方法です。XMLBeans を使用して SAMLResponse を解析し、復号化し (暗号化されている場合)、署名を検証します。

WebBrowserSSOAuthConsumerService

于 2011-07-14T15:23:13.893 に答える
1

コードを要求するのは少々手間がかかりますが、基本的な処理は、SP が SAMLResponse を検証することです。これには、整形式であること、必要な値の存在、正しいプロトコル、およびその他の SP 固有の検証 (時間の制約、データの対応など) が含まれます。 )、トークンで識別されたユーザーを SP 上のユーザーにマップし (ユーザーの作成を伴う場合があります)、要求されたリソースにユーザーを転送します。

于 2011-07-13T18:50:11.977 に答える