Spring Integration Yoda が登場
私は、JSF アプリケーションから起動された JavaScript ウィジェットへの REST Web サービス呼び出しを有効にすることに取り組んでいます。サービスの実装は REST easy に既に存在し、OAuth 2.0 セキュリティは含まれていません。目標は、セキュリティ ゲートウェイを介してすべての JS 呼び出しを渡しながら、サービスをそのままにしておくことです。
目標を達成するために、Mule Enterprise で最初のプロトタイプを作成し、Spring セキュリティの OAuth 拡張と HTTP インバウンド/アウトバウンド エンドポイントを使用しました。これは Mule が提案したアプローチでした。
その後、私の 2 番目のプロトタイプは、Spring Security/Spring の統合に関するものです。そして、本質的に同じ OAuth 2.0 プロバイダー、セキュリティ ルール、および HTTP インバウンド/アウトバウンド ゲートウェイです。春のサポートで作業しているときに、これはうまくいかないと言われました(理由は以下)。私の理解では、Mule と SI は非常に似ており、1 つの「接着剤」を別の接着剤に置き換えることができるはずです。これは SI の想定された用途ではないかもしれません。まだ使用できるかどうかを検証したいと思います。
また、基本的にパイプを作成してオーバーヘッドを削減するゲートウェイの構成は何ですか?
私の理論を検証または反証するために時間を割いていただきありがとうございます。
イレナ
構成コードの抜粋:
<sec:http pattern="/mycompany/api/myws/service/v[^/]+/.*" request-matcher="regex"
create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint"
use-expressions="true" >
<sec:anonymous enabled="false" />
<sec:intercept-url pattern="/mycompany/api/myws/service/v[^/]+/gateway1/op1\?([^&]+&)*tenant=[0-9]+(&[^&]+)*"
access="#oauth2.hasAnyScope('SCOPE1', 'SCOPE2', 'SCOPE3') and #mycompany.tenantAllowed()"
method="GET" />
<sec:intercept-url pattern="/mycompany/api/myws/service/v[^/]+/gateway2/op1\?([^&]+&)*tenant=[0-9]+(&[^&]+)*"
access="#oauth2.hasAnyScope('SCOPE1', 'SCOPE2', 'SCOPE3') and #mycompany.tenantAllowed() and hasRole('ROLE1')"
method="GET" />
<sec:intercept-url pattern="/mycompany/api/myws/service/v[^/]+/gateway3/tenant/[0-9]+/identifier1/[0-9]+(/identifier2/[0-9]+)?(\?.+)?"
access="#oauth2.hasAnyScope('SCOPE1', 'SCOPE2', 'SCOPE3') and #mycompany.tenantAllowed() and #mycompany.identifier1Allowed() and hasRole('ROLE1')"
method="GET" />
<sec:intercept-url pattern="/mycompany/api/myws/service/v[^/]+/gateway3/tenant/[0-9]+/identifier1/[0-9]+/op1(\?.+)?"
access="#oauth2.hasAnyScope('SCOPE1', 'SCOPE2', 'SCOPE3') and #mycompany.tenantAllowed() and #mycompany.identifier1Allowed() and #mycompany.issuedForIdentifier1() and hasRole('ROLE1')"
method="POST" />
<sec:intercept-url pattern="/mycompany/api/myws/service/v[^/]+/gateway3/tenant/[0-9]+/identifier1/[0-9]+/op2(\?.+)?"
access="#oauth2.hasAnyScope('SCOPE1', 'SCOPE2', 'SCOPE3') and #mycompany.tenantAllowed() and #mycompany.identifier1Allowed() and hasRole('ROLE1')"
method="POST" />
<sec:intercept-url pattern="/mycompany/api/myws/service/v[^/]+/gateway3/op3/tenant/[0-9]+/identifier1/[0-9]+/identifier3/[^/]+/identifier4/[0-9]+(\?.+)?"
access="#oauth2.hasAnyScope('SCOPE1', 'SCOPE2', 'SCOPE3') and #mycompany.tenantAllowed() and #mycompany.identifier1Allowed() and #mycompany.issuedForIdentifier1() and hasRole('ROLE2')"
method="POST" />
<sec:intercept-url pattern="/mycompany/api/myws/service/v[^/]+/.*" access="denyAll()" />
<sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<sec:access-denied-handler ref="oauthAccessDeniedHandler" />
<sec:expression-handler ref="oauthWebExpressionHandler" />
</sec:http>
<int-http:inbound-gateway id="gateway1op1"
request-payload-type="java.lang.String"
supported-methods="GET"
request-channel="mywsRequest"
reply-channel="mywsResponse"
path="/mycompany/api/myws/service/{version}/gateway1/op1"
>
<int-http:header name="outboundMethod" expression="'GET'"/>
<int-http:header name="version" expression="#pathVariables.version"/>
<int-http:header name="pathInfo" expression="'gateway1/op1'"/>
<int-http:header name="queryString" expression="'?tenant=' + #requestParams['tenant']
+ '&query=' + #requestParams['query']
+ (#requestParams['format'] != null?'&format=' + #requestParams['format']:'')
+ (#requestParams['identifier0'] != null?'&identifier0=' + #requestParams['identifier0']:'') "/>
</int-http:inbound-gateway>
<int-http:inbound-gateway id="gateway2op1"
request-payload-type="java.lang.String"
supported-methods="GET"
request-channel="mywsRequest"
reply-channel="mywsResponse"
path="/mycompany/api/myws/service/{version}/gateway2/op1"
>
<int-http:header name="outboundMethod" expression="'GET'"/>
<int-http:header name="version" expression="#pathVariables.version"/>
<int-http:header name="pathInfo" expression="'gateway2/op1'"/>
<int-http:header name="queryString" expression="'?tenant=' + #requestParams['tenant']
+ (#requestParams['format'] != null?'&format=' + #requestParams['format']:'')
+ T(com.google.common.base.Joiner).on('').skipNulls().join(#requestParams['type'] .!['&type=' + #this]) "/>
</int-http:inbound-gateway>
<int-http:inbound-gateway id="gateway3op1"
request-payload-type="java.lang.String"
supported-methods="GET"
request-channel="mywsRequest"
reply-channel="mywsResponse"
path="/mycompany/api/myws/service/{version}/gateway3/tenant/{tenant}/identifier1/{identifier1}"
>
<int-http:header name="outboundMethod" expression="'GET'"/>
<int-http:header name="version" expression="#pathVariables.version"/>
<int-http:header name="pathInfo" expression="'gateway3/tenant/' + #pathVariables.tenant + '/identifier1/' + #pathVariables.identifier1"/>
<int-http:header name="queryString" expression="(#requestParams['format'] != null?'?format=' + #requestParams['format']:'') "/>
</int-http:inbound-gateway>
<int-http:inbound-gateway id="gateway3Info"
request-payload-type="java.lang.String"
supported-methods="GET"
request-channel="mywsRequest"
reply-channel="mywsResponse"
path="/mycompany/api/myws/service/{version}/gateway3/tenant/{tenant}/identifier1/{identifier1}/identifier2/{identifier2}"
>
<int-http:header name="outboundMethod" expression="'GET'"/>
<int-http:header name="version" expression="#pathVariables.version"/>
<int-http:header name="pathInfo" expression="'gateway3/tenant/' + #pathVariables.tenant + '/identifier1/' + #pathVariables.identifier1 + '/identifier2/' + #pathVariables.identifier2"/>
<int-http:header name="queryString" expression="(#requestParams['format'] != null?'?format=' + #requestParams['format']:'') "/>
</int-http:inbound-gateway>
<int-http:inbound-gateway id="gateway3op1op2"
supported-methods="POST"
request-channel="mywsRequest"
reply-channel="mywsResponse"
path="/mycompany/api/myws/service/{version}/gateway3/tenant/{tenant}/identifier1/{identifier1}/{command}"
>
<int-http:header name="outboundMethod" expression="'POST'"/>
<int-http:header name="version" expression="#pathVariables.version"/>
<int-http:header name="pathInfo" expression="'gateway3/tenant/' + #pathVariables.tenant + '/identifier1/' + #pathVariables.identifier1 + '/' + #pathVariables.command"/>
<int-http:header name="queryString" expression="(#requestParams['format'] != null?'?format=' + #requestParams['format']:'') "/>
</int-http:inbound-gateway>
<int-http:inbound-gateway id="gateway3op3"
supported-methods="POST"
request-channel="mywsRequest"
reply-channel="mywsResponse"
path="/mycompany/api/myws/service/{version}/gateway3/op3/tenant/{tenant}/identifier1/{identifier1}/identifier3/{identifier3}/identifier4/{identifier4}"
>
<int-http:header name="outboundMethod" expression="'POST'"/>
<int-http:header name="version" expression="#pathVariables.version"/>
<int-http:header name="pathInfo" expression="'gateway3/op3/tenant/' + #pathVariables.tenant + '/identifier1/' + #pathVariables.identifier1 + '/identifier3/' + #pathVariables.identifier3 + '/identifier4/' + #pathVariables.identifier4"/>
<int-http:header name="queryString" expression="(#requestParams['format'] != null?'?format=' + #requestParams['format']:'') "/>
</int-http:inbound-gateway>
<int:channel id="mywsRequest" />
<int:channel id="mywsResponse" />
<int-http:outbound-gateway request-channel="mywsRequest" reply-channel="mywsResponse"
url-expression="@accessor.mywsEndpoint + headers.pathInfo + headers.queryString"
http-method-expression="headers.outboundMethod"
expected-response-type="java.lang.String"
request-factory="customRequestFactory"
>
サポートの返信:
SI はおそらくこの種の機能には適していません。理由は次のとおりです。
spring 統合は、メッセージに「メッセージ」タイプを使用します。チャネルに入るすべてのものは、タイプが「メッセージ」である必要があります。これは事実上、すべての HttpRequest を SI メッセージに変換する必要があり、その逆も同様であることを意味します。HttpResponse も同様です。
spring 統合は HttpRequest オブジェクトを直接公開しません。むしろ、リクエスト処理を簡素化する SI で暗黙的に内部的に処理されます。つまり、リクエストパラメーター、ヘッダー値、パス変数への簡単なアクセス...しかし、あなたの場合、これは複雑です。そして複雑さは、インバウンド ゲートウェイの構成で見ることができます。
特に大規模なリクエスト (ファイルのアップロードなど) の場合は、より一般的な問題が後で発生する可能性があります。このようなリクエストはすべて、プロキシのメモリ内で内部的に処理されるため、問題が発生する可能性があります
すべてのリクエストが個別のスレッドで処理されるため、同時実行パフォーマンスの問題が発生する可能性がありますが、この問題は SI 固有ではありません
代理目的で SI を使用することを再考する理由をいくつか挙げました。この決定を下した理由はわかりませんが、これに関する例、チュートリアル、またはブログ投稿を見たことがありますか? はいの場合はお知らせください。確認します。
今後どのような決断を下すかは、あなた次第です。しかし同時に、これは技術サポートの範囲を超えているため、代わりに何を使用するかについては何も考えていません. しかし、ご興味がありましたら、当社の技術担当者に連絡し、コンサルティング サービスを手配することができます。