3

OpenSAMLを使用してSalesForceのSSOを実装しようとしました。私のコードは、salesforceSAMLバリデーターによって検証された有効なSAMLアサーションを生成します。しかし、セールスフォースにアサーションを送信しようとすると、常に次のエラーが発生しました。

{"error_uri":"https://na4.salesforce.comnull/setup/secur/SAMLValidationPage.apexp","error":"invalid_grant","error_description":"invalid assertion"}

次のコードを使用して、セールスフォースにリクエストを送信します。

    SAMLResponseGenerator responseGenerator = new SalesforceSAMLResponseGenerator(container, strIssuer, strNameID, strNameQualifier, sessionId);

    String samlAssertion = Base64.encodeBase64String(responseGenerator.generateSAMLAssertionString());
    try {
        HttpClient httpClient = createHttpClient();
        HttpPost httpPost = new HttpPost("https://login.salesforce.com/services/oauth2/token");
        MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
        entity.addPart("grant_type", new StringBody("assertion"));
        entity.addPart("assertion_type", new StringBody("urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser"));
        entity.addPart("assertion", new StringBody(samlAssertion));
        httpPost.setEntity(entity);
        HttpResponse httpResponse = httpClient.execute(httpPost);

        // Get the response
        BufferedReader rd = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
        StringBuffer buffer = new StringBuffer();
        String line = null;
        while ((line = rd.readLine()) != null) {
            buffer.append(line);
            buffer.append("\n");
        }
        rd.close();
        httpClient.getConnectionManager().shutdown();
        System.out.println(buffer.toString());
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

私のジェネレーターは有効なSAMLを生成しました(salesforce SAMLバリデーターの結果を信頼できる場合)。samlAssertionの代わりにランダムデータを送信したときに同じエラーメッセージを受け取ったため、salesforceはアサーションをデコードできないようです。

また、Base64.encodeBase64URLSafeString()を使用してエンコードしようとしましたが、肯定的な結果は得られませんでした。

誰かがこの問題で私を助けることができますか?

4

1 に答える 1

2

私の問題の解決は非常に簡単でした。SalesForceのドキュメントを信頼せず、プロトコル仕様のみを信頼してください:)仕様に従って、Base64でエンコードされたSAMLをSAMLResponseパラメーターで送信する必要があります。以上です。

私は次のコードを使用して解決策を説明しました:

    HttpClient httpClient = initHttpClient();
    HttpPost httpPost = new HttpPost("https://login.salesforce.com/");
    MultipartEntity entity = new MultipartEntity(HttpMultipartMode.STRICT);
    entity.addPart("SAMLResponse", new StringBody(Base64.encodeBase64String(samlAssertion)));
    httpPost.setEntity(entity);
    HttpResponse httpResponse = httpClient.execute(httpPost);

    Header location = httpResponse.getFirstHeader("Location");
    if (null != location) {
        System.out.println(location.getValue());
    }
于 2012-09-06T10:50:15.017 に答える