差分
このページの2つのバージョン間の差分を表示します。
| 次のリビジョン | 前のリビジョン | ||
| study:java:sharepointonline:implement3 [2021/07/19 08:29] – 作成 banana | study:java:sharepointonline:implement3 [2025/02/03 09:17] (現在) – banana | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| ====== Binary token取得の実装 ====== | ====== Binary token取得の実装 ====== | ||
| - | 本稿では、[[study: | + | 本稿では、[[study: |
| + | 動作環境については、上記ページに紹介してありますので、割愛します。 | ||
| + | |||
| + | {{keywords> | ||
| + | |||
| + | ====== Mainコード ====== | ||
| + | 実装コードのメインとなる部分を以下に示します。 | ||
| + | <code java> | ||
| + | private static final ResourceBundle RSC = ResourceBundle.getBundle(" | ||
| + | private static final String CUSTOM_STS_ENDPOINT = " | ||
| + | |||
| + | private Map< | ||
| + | static { | ||
| + | //register the prefix of NameSpace | ||
| + | namespacePrefixes.put(" | ||
| + | } | ||
| + | |||
| + | public String receiveBinarySecurityToken(String samlAssertion) { | ||
| + | String _token = ""; | ||
| + | try { | ||
| + | //request entity | ||
| + | RequestEntity< | ||
| + | .post(new URI(CUSTOM_STS_ENDPOINT)) | ||
| + | .header(" | ||
| + | .body(buildBinaryTokenRequestEnvelope(samlAssertion)); | ||
| + | |||
| + | RestTemplate _restTemplate = new RestTemplate(); | ||
| + | _restTemplate.setRequestFactory(buildProxyClientHttpRequestFactory()); | ||
| + | |||
| + | ResponseEntity< | ||
| + | DOMResult _result = new DOMResult(); | ||
| + | |||
| + | Transformer _transformer = TransformerFactory.newInstance().newTransformer(); | ||
| + | _transformer.transform(new StringSource(_responseEntity.getBody()), | ||
| + | |||
| + | Document _definitionDocument = (Document) _result.getNode(); | ||
| + | final String XPATH_EXPRESSION = "// | ||
| + | _token = getXPathExpression(XPATH_EXPRESSION).evaluateAsString(_definitionDocument); | ||
| + | |||
| + | if ("" | ||
| + | logger.error(" | ||
| + | } | ||
| + | |||
| + | } catch (Exception e) { | ||
| + | logger.error(" | ||
| + | } | ||
| + | |||
| + | return _token; | ||
| + | }// | ||
| + | |||
| + | //build Binary token request envelope | ||
| + | private String buildBinaryTokenRequestEnvelope(String samlAssertion) { | ||
| + | //SAML Assertion mapping | ||
| + | Map< | ||
| + | _mapRequest.put(" | ||
| + | _mapRequest.put(" | ||
| + | //replace placeHolder | ||
| + | StringSubstitutor _substitutor = new StringSubstitutor(_mapRequest, | ||
| + | String _finalXMLRequest = _substitutor.replace(RSC.getString(" | ||
| + | |||
| + | return _finalXMLRequest; | ||
| + | }// | ||
| + | |||
| + | //build HttpComponentsClientHttpRequestFactory for PROXY connection | ||
| + | private HttpComponentsClientHttpRequestFactory buildProxyClientHttpRequestFactory() throws Exception { | ||
| + | return ProxyClientHttpRequestFactoryBuilder.build()); | ||
| + | } | ||
| + | |||
| + | //create XPathExpression | ||
| + | private XPathExpression getXPathExpression(String expression) { | ||
| + | XPathExpression _xPathExpressioin = XPathExpressionFactory.createXPathExpression(expression, | ||
| + | return _xPathExpressioin; | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | ★ポイント1\\ | ||
| + | SOAPリクエストメッセージを作成する部分です。\\ | ||
| + | %(samltoken)部分をSAML security token(SAML Assertion)に置換します。\\ | ||
| + | %(siteurl)部分は、SharepointサイトURLに置換します。\\ | ||
| + | appliction.propertiesの一部分を以下に示します。 | ||
| + | < | ||
| + | site.url=SharepointサイトURL | ||
| + | soap.binary.token.request=< | ||
| + | </ | ||
| + | |||
| + | ★ポイント2\\ | ||
| + | ここからの処理は外部サイトにアクセスするので、Proxy環境にある場合はProxy設定と、Https通信設定が必要です。\\ | ||
| + | 詳細は次節を参照してください。 | ||
| + | |||
| + | ★ポイント3\\ | ||
| + | レスポンスXMLから、XPathを利用してBinary tokenを抽出します。\\ | ||
| + | wsse: | ||
| + | |||
| + | ====== ProxyClientHttpRequestFactoryBuilderクラス ====== | ||
| + | ProxyClientHttpRequestFactoryBuilderクラスのコードを以下に示します。 | ||
| + | <code java> | ||
| + | public class ProxyClientHttpRequestFactoryBuilder { | ||
| + | private static final String PROXY_HOST = " | ||
| + | private static final int PROXY_PORT = 8080; | ||
| + | |||
| + | public static HttpComponentsClientHttpRequestFactory build() throws Exception { | ||
| + | HttpHost _proxy = new HttpHost(PROXY_HOST, | ||
| + | |||
| + | final int TIMEOUT = 5; | ||
| + | |||
| + | //request configuration | ||
| + | RequestConfig _reqConfig = RequestConfig.custom() | ||
| + | .setConnectTimeout(TIMEOUT * 1000) | ||
| + | .setSocketTimeout(TIMEOUT * 1000) | ||
| + | .setConnectionRequestTimeout(TIMEOUT * 1000) | ||
| + | .setProxy(_proxy) | ||
| + | .build(); | ||
| + | |||
| + | BouncyCastleFipsProviderHelper.setUpProvider(); | ||
| + | |||
| + | //setup SSLContext(BouncyCastle provider) | ||
| + | SSLContext _sslContext = SSLContexts.custom() | ||
| + | .setProvider(new BouncyCastleJsseProvider(true)) | ||
| + | .build(); | ||
| + | |||
| + | SSLConnectionSocketFactory _sslSocketFactory = new SSLConnectionSocketFactory(_sslContext, | ||
| + | new String[]{" | ||
| + | new String[]{" | ||
| + | " | ||
| + | new DefaultHostnameVerifier()); | ||
| + | |||
| + | Registry< | ||
| + | .register(" | ||
| + | .register(" | ||
| + | .build(); | ||
| + | |||
| + | PoolingHttpClientConnectionManager _cm = new PoolingHttpClientConnectionManager(_socketFactoryRegistry); | ||
| + | _cm.setMaxTotal(200); | ||
| + | _cm.setDefaultMaxPerRoute(100); | ||
| + | |||
| + | //create HttpClient | ||
| + | HttpClient _client = HttpClientBuilder.create() | ||
| + | .setUserAgent(" | ||
| + | .setConnectionManager(_cm) | ||
| + | .disableRedirectHandling() | ||
| + | .setDefaultRequestConfig(_reqConfig) | ||
| + | .build(); | ||
| + | |||
| + | HttpComponentsClientHttpRequestFactory _factory = new HttpComponentsClientHttpRequestFactory(_client); | ||
| + | |||
| + | return _factory; | ||
| + | }//build | ||
| + | |||
| + | } | ||
| + | </ | ||
| + | |||
| + | ★ポイント1 | ||
| + | HTTP Proxyを設定する部分です。ID/ | ||
| + | |||
| + | ★ポイント2 | ||
| + | Bouncy CastleプロバイダーをSecurity Providerとして登録する部分です。\\ | ||
| + | 詳細については、[[study: | ||
| + | |||
| + | ★ポイント3 | ||
| + | FIPSモードとしてBouncy castleプロバイダーを設定します。 | ||
| + | |||
| + | ★ポイント4 | ||
| + | Cipher Suiteを指定します。 Java 7環境では、key size制限(128)があるため、Sharepointサイト要求のCipher Suiteから128lengthのみを選択します。\\ | ||
| + | この指定がないと、「java.security.InvalidKeyException: | ||
| + | |||
| + | ~~DISCUSSION~~ | ||