差分
このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
| study:java:sharepointonline:implement1 [2021/07/15 09:27] – [Main class code] banana | study:java:sharepointonline:implement1 [2025/02/07 05:18] (現在) – [SAML Security token 取得の実装] banana | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| ====== SAML Security token 取得の実装 ====== | ====== SAML Security token 取得の実装 ====== | ||
| ここでは、[[study: | ここでは、[[study: | ||
| - | + | {{keywords> | |
| - | ===== 動作環境について ===== | + | ====== 動作環境について |
| テスト環境についてですが、Java7(IBM J9 VM (build 2.6, JRE 1.7.0 Windows 7 amd64-64 Compressed References 20150701_255667 (JIT enabled, AOT enabled))で、テストを行いました。\\ | テスト環境についてですが、Java7(IBM J9 VM (build 2.6, JRE 1.7.0 Windows 7 amd64-64 Compressed References 20150701_255667 (JIT enabled, AOT enabled))で、テストを行いました。\\ | ||
| ビルドには、Mavenを使用しました。\\ | ビルドには、Mavenを使用しました。\\ | ||
| 行 39: | 行 39: | ||
| 特に注目して欲しい のは、boucycastleライブラリです。bouncycastleライブラリを導入する理由については、Binary token取得のjava実装編で紹介します。 | 特に注目して欲しい のは、boucycastleライブラリです。bouncycastleライブラリを導入する理由については、Binary token取得のjava実装編で紹介します。 | ||
| - | ===== Main class code ===== | + | ====== Main class code ====== |
| 実装のメインになるコードを以下に示します。\\ | 実装のメインになるコードを以下に示します。\\ | ||
| <code java> | <code java> | ||
| 行 59: | 行 59: | ||
| | | ||
| | | ||
| - | | + | |
| RestTemplate _restTemplate = new RestTemplate(); | RestTemplate _restTemplate = new RestTemplate(); | ||
| - | _restTemplate.setRequestFactory(buildHttpComponentsClientHttpRequestFactory()); | + | _restTemplate.setRequestFactory(buildHttpComponentsClientHttpRequestFactory()); |
| ResponseEntity< | ResponseEntity< | ||
| 行 70: | 行 70: | ||
| Document _definitionDocument = (Document) _result.getNode(); | Document _definitionDocument = (Document) _result.getNode(); | ||
| - | final String XPATH_EXPRESSION = "// | + | final String XPATH_EXPRESSION = "// |
| Node _tokenNode = getXPathExpression(XPATH_EXPRESSION).evaluateAsNode(_definitionDocument); | Node _tokenNode = getXPathExpression(XPATH_EXPRESSION).evaluateAsNode(_definitionDocument); | ||
| - | _token = nodeToXmlString(_tokenNode); | + | _token = nodeToXmlString(_tokenNode); |
| if ("" | if ("" | ||
| 行 84: | 行 84: | ||
| }// | }// | ||
| - | | + | |
| + | private String buildSamlSecurityRequestEnvelope() { | ||
| + | //UserName token mapping | ||
| + | Map< | ||
| + | _mapRequest.put(" | ||
| + | _mapRequest.put(" | ||
| + | _mapRequest.put(" | ||
| + | //replace placeHolder | ||
| + | StringSubstitutor _substitutor = new StringSubstitutor(_mapRequest, | ||
| + | String _finalXMLRequest = _substitutor.replace(RSC.getString(" | ||
| + | |||
| + | return _finalXMLRequest; | ||
| + | }// | ||
| + | |||
| + | private HttpComponentsClientHttpRequestFactory buildHttpComponentsClientHttpRequestFactory() throws Exception { | ||
| + | return HttpComponentsClientHttpRequestFactoryBuilder.build(); | ||
| + | } | ||
| + | |||
| + | //create xPathExpression | ||
| + | private XPathExpression getXPathExpression(String expression) { | ||
| + | XPathExpression _xPathExpressioin = XPathExpressionFactory.createXPathExpression(expression, | ||
| + | return _xPathExpressioin; | ||
| + | } | ||
| + | |||
| + | //convert nodes to XML string | ||
| + | private String nodeToXmlString(Node node) throws Exception { | ||
| + | StringWriter _writer = new StringWriter(); | ||
| + | Transformer _transformer = TransformerFactory.newInstance().newTransformer(); | ||
| + | _transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, | ||
| + | _transformer.setOutputProperty(OutputKeys.INDENT, | ||
| + | _transformer.transform(new DOMSource(node), | ||
| + | |||
| + | return _writer.toString(); | ||
| + | } | ||
| </ | </ | ||
| + | ★Point1\\ | ||
| + | SAML requestメッセージを作成する部分になります。\\ | ||
| + | SOAP Envelopeメッセージ(xml)は、application.propertiesに格納されています。\\ | ||
| + | application.propertiesの中身を以下に示します。 | ||
| + | <code properties> | ||
| + | soap.auth.username=Sharepointユーザーアカウント | ||
| + | soap.auth.password=ユーザーパスワード | ||
| + | soap.saml.token.request=< | ||
| + | |||
| + | </ | ||
| + | |||
| + | ★Point2\\ | ||
| + | HttpComponentsClientHttpRequestFactoryを作成する部分です。\\ | ||
| + | ごく一般的設定になりますが、ポイントとしてUser-Agentの指定です。((User-Agentを指定する理由は、SharePointサイトからの調整を回避するためです。詳細は[[https:// | ||
| + | コードの一部分を以下に示します。 | ||
| + | <code java> | ||
| + | public class HttpComponentsClientHttpRequestFactoryBuilder { | ||
| + | public static HttpComponentsClientHttpRequestFactory build() { | ||
| + | final int TIMEOUT = 5; | ||
| + | //create connection manager | ||
| + | PoolingHttpClientConnectionManager _cm = new PoolingHttpClientConnectionManager(); | ||
| + | _cm.setMaxTotal(128); | ||
| + | _cm.setDefaultMaxPerRoute(24); | ||
| + | |||
| + | //request configuration | ||
| + | RequestConfig _requestConfig = RequestConfig.custom() | ||
| + | .setConnectTimeout(TIMEOUT * 1000) | ||
| + | .setConnectionRequestTimeout(TIMEOUT * 1000) | ||
| + | .setSocketTimeout(TIMEOUT * 1000) | ||
| + | .build(); | ||
| + | |||
| + | //create HttpClient | ||
| + | HttpClientBuilder _builder = HttpClientBuilder.create() | ||
| + | .setUserAgent(" | ||
| + | .setConnectionManager(_cm) | ||
| + | .setDefaultRequestConfig(_requestConfig); | ||
| + | |||
| + | HttpComponentsClientHttpRequestFactory _factory = new HttpComponentsClientHttpRequestFactory(_builder.build()); | ||
| + | |||
| + | return _factory; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | </ | ||
| + | |||
| + | ★Point3\\ | ||
| + | SAML: | ||
| + | elementがnamespaceのものならXPathExpression生成時、namespaceを渡す必要があります。\\ | ||
| + | |||
| + | ★Point4\\ | ||
| + | 取り出したSAML: | ||
| + | そのため、ここでNodeをStringに変換しています。 | ||
| + | |||
| + | ~~DISCUSSION~~ | ||