Spring security 我可以使用spring集成和spring安全性来创建OAuth 2.0反向代理吗?

Spring security 我可以使用spring集成和spring安全性来创建OAuth 2.0反向代理吗?,spring-security,spring-integration,spring-security-oauth2,Spring Security,Spring Integration,Spring Security Oauth2,春天,尤达在那里 我正在致力于支持对JSF应用程序中启动的JavaScript小部件的RESTWeb服务调用。这些服务的实现已经存在于REST easy上,并且不包括OAuth 2.0安全性。目标是让服务保持原样,同时通过安全网关传递所有JS调用 为了实现这一目标,我首先在Mule Enterprise上开发了我的第一个原型,它的OAuth增强了spring安全性和HTTP入站/出站端点。这就是骡子建议的方法 之后,我的第二个原型是关于SpringSecurity/SpringIntegrati

春天,尤达在那里

我正在致力于支持对JSF应用程序中启动的JavaScript小部件的RESTWeb服务调用。这些服务的实现已经存在于REST easy上,并且不包括OAuth 2.0安全性。目标是让服务保持原样,同时通过安全网关传递所有JS调用

为了实现这一目标,我首先在Mule Enterprise上开发了我的第一个原型,它的OAuth增强了spring安全性和HTTP入站/出站端点。这就是骡子建议的方法

之后,我的第二个原型是关于SpringSecurity/SpringIntegration的。本质上是相同的OAuth 2.0提供程序、安全规则和HTTP入站/出站网关。在使用spring支持时,我被告知这不起作用(原因如下)。据我所知,Mule和SI非常相似,我应该能够用另一种“胶水”替换一种“胶水”。这可能不是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\?([^&amp;]+&amp;)*tenant=[0-9]+(&amp;[^&amp;]+)*"
        access="#oauth2.hasAnyScope('SCOPE1', 'SCOPE2', 'SCOPE3') and #mycompany.tenantAllowed()"
        method="GET" /> 
    <sec:intercept-url pattern="/mycompany/api/myws/service/v[^/]+/gateway2/op1\?([^&amp;]+&amp;)*tenant=[0-9]+(&amp;[^&amp;]+)*"
        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']
        + '&amp;query=' +  #requestParams['query']
        + (#requestParams['format'] != null?'&amp;format=' + #requestParams['format']:'') 
        + (#requestParams['identifier0'] != null?'&amp;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?'&amp;format=' + #requestParams['format']:'') 
        + T(com.google.common.base.Joiner).on('').skipNulls().join(#requestParams['type'] .!['&amp;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内部隐式处理的,这简化了 请求处理。i、 e.对请求参数、标题的简单访问 值、路径变量。。。但在你的情况下,这是一个复杂的问题。及 复杂情况在入站网关配置中可见

  • 更一般的问题可能会在以后出现,尤其是在大型请求(即文件上载)的情况下。所有这些请求都将得到处理 在代理的内存中,这可能会导致问题

  • 可能存在并发性能问题,因为每个请求都将在单独的线程中处理,但是这个问题不是SI 具体的

我给了你一些重新考虑使用SI代理的理由。我是 不确定是什么促使你做出这个决定,你看到了吗 例如,关于这方面的教程或博客文章?如果需要,请告诉我 是的,我去看看

未来的决定取决于你自己。但同时 时间,我不会给你任何想法,用什么代替,因为这是 超出技术支持的范围。但如果你感兴趣的话 我可以联系我们的工程部,为您安排咨询服务 你


你到底想解决什么问题?你说你想“减少开销”,但没有说那是什么,或者什么是不起作用的。我想实现的是获得一个管道行为是可能的:在不转换为消息和返回或最小转换的情况下移交字节。如果使用Spring Integration作为入站通道,则无法停止正在创建的
消息。如果您关心这一点,您可能可以在HTTP请求中保留
字节[]
,但它们必须包装在
消息中
,否则Spring Integration中的任何内容都不知道如何处理它们。也许这就是您的支持查询响应的内容。