如何在 Mule 上记录 WS Security 用户名和 SOAP 方法
How to log WS Security username and SOAP method on Mule
我有一个应用程序将验证用户名和密码以提供对 soap 网络服务的访问权限,我正在尝试记录所使用的用户名和方法,那么如何将该信息记录到数据库中(获取用户和方法)?
这是我目前的代码:
<mule-ss:security-manager
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security">
<mule-ss:delegate-security-provider
name="jdbc-provider" delegate-ref="authenticationManager" />
</mule-ss:security-manager>
<spring:beans>
<spring:bean id="loggingInInterceptor"
class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<spring:bean id="loggingOutInterceptor"
class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<spring:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<spring:property name="driverClassName" value="org.postgresql.Driver" />
<spring:property name="url" value="jdbc:postgresql://127.0.0.1/anydb" />
<spring:property name="username" value="anyuser" />
<spring:property name="password" value="0123456" />
</spring:bean>
<ss:http xmlns:ss="http://www.springframework.org/schema/security"
auto-config="true" use-expressions="true" request-matcher="regex">
<ss:intercept-url pattern="^/services/any/anyservice"
access="hasRole('ROLE_ANY')" />
</ss:http>
<ss:authentication-manager
xmlns:ss="http://www.springframework.org/schema/security" alias="authenticationManager">
<ss:authentication-provider>
<ss:jdbc-user-service data-source-ref="dataSource"
users-by-username-query="
select username, password, enabled
from users where username=?"
authorities-by-username-query="
select u.username, ur.authority from users u, authorities ur
where u.id = ur.user_id and u.username =? " />
</ss:authentication-provider>
</ss:authentication-manager>
</spring:beans>
<jdbc:postgresql-data-source name="postgreName"
user="anyuser" password="0123456" url="jdbc:postgresql://127.0.0.1/anyservice"
transactionIsolation="UNSPECIFIED" doc:name="PostgreSQL Data Source">
</jdbc:postgresql-data-source>
<jdbc:connector name="jdbcConnector" dataSource-ref="postgreName"
validateConnections="false" queryTimeout="10" pollingFrequency="10000"
doc:name="Database">
<reconnect frequency="3000" blocking="false" />
<jdbc:query key="anydb" value="insert into inbound_msgs (ip_from, request_size, modified_request_size, timestamp, url)
values (
#[groovy: return message.getInboundProperty('MULE_REMOTE_CLIENT_ADDRESS').toString()],
#[groovy: return message.getInboundProperty('http.request.old').toString().length()],
#[groovy: return message.getInboundProperty('http.request').toString().length()],
now(),
#[groovy: return message.getInboundProperty('http.context.uri').toString()]);">
</jdbc:query>
</jdbc:connector>
<scripting:transformer name="noopLoggingTransformer"
doc:name="Script">
<scripting:script engine="groovy">
def props = [:]
//props['User-Agent'] = message.getProperty('User-Agent', org.mule.api.transport.PropertyScope.INBOUND)
props['MULE_REMOTE_CLIENT_ADDRESS'] =
message.getProperty('MULE_REMOTE_CLIENT_ADDRESS',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.context.uri'] = message.getProperty('http.context.uri',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request.old'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
muleContext.client.dispatch('vm://log-request.in', payload, props)
message
</scripting:script>
</scripting:transformer>
<flow name="log-request" doc:name="log-request">
<vm:inbound-endpoint path="log-request.in"
doc:name="VM" />
<jdbc:outbound-endpoint exchange-pattern="one-way"
queryKey="anydb" responseTimeout="10000" queryTimeout="10"
connector-ref="jdbcConnector" doc:name="Persist raw message">
</jdbc:outbound-endpoint>
</flow>
<pattern:web-service-proxy name="logBypass" doc:name="logBypass">
<inbound-endpoint address="http://localhost/services/logBypass" exchange-pattern="request-response" transformer-refs="noopLoggingTransformer">
<mule-ss:http-security-filter realm="mule-realm"></mule-ss:http-security-filter>
</inbound-endpoint>
<outbound-endpoint address="http://targetServer/logBypass" exchange-pattern="request-response"/>
</pattern:web-service-proxy>
Mule 版本 3.4.0
几天后我找到了解决问题的方法:
与:
<scripting:transformer name="noopLoggingTransformer"
doc:name="Script">
<scripting:script engine="groovy">
import org.apache.commons.codec.binary.Base64
def props = [:]
//props['User-Agent'] = message.getProperty('User-Agent', org.mule.api.transport.PropertyScope.INBOUND)
props['MULE_REMOTE_CLIENT_ADDRESS'] =
message.getProperty('MULE_REMOTE_CLIENT_ADDRESS',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.context.uri'] = message.getProperty('http.context.uri',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request.old'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
def headerData = message.getProperty('http.headers',org.mule.api.transport.PropertyScope.INBOUND)
def userName = ""
if (headerData["Authorization"] != null) {
def security = headerData["Authorization"].split(" ")
def bytes = security[1].bytes
Base64 coder = new Base64()
def decodedData = coder.decode(bytes)
def userNamePwd = new String(decodedData)
def userNameSplit = userNamePwd.split(":")
userName = userNameSplit[0]
}
props['userName'] = userName
def method = ""
if (headerData["SOAPAction"] != null) {
method = headerData["SOAPAction"]
}
props['method'] = method
muleContext.client.dispatch('vm://log-request.in', payload, props)
message
</scripting:script>
</scripting:transformer>
那个和问题中的代码将在 Mule 3.4.0 上完美运行
请记住更改数据库以适应您的需要。
我有一个应用程序将验证用户名和密码以提供对 soap 网络服务的访问权限,我正在尝试记录所使用的用户名和方法,那么如何将该信息记录到数据库中(获取用户和方法)?
这是我目前的代码:
<mule-ss:security-manager
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security">
<mule-ss:delegate-security-provider
name="jdbc-provider" delegate-ref="authenticationManager" />
</mule-ss:security-manager>
<spring:beans>
<spring:bean id="loggingInInterceptor"
class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<spring:bean id="loggingOutInterceptor"
class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<spring:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<spring:property name="driverClassName" value="org.postgresql.Driver" />
<spring:property name="url" value="jdbc:postgresql://127.0.0.1/anydb" />
<spring:property name="username" value="anyuser" />
<spring:property name="password" value="0123456" />
</spring:bean>
<ss:http xmlns:ss="http://www.springframework.org/schema/security"
auto-config="true" use-expressions="true" request-matcher="regex">
<ss:intercept-url pattern="^/services/any/anyservice"
access="hasRole('ROLE_ANY')" />
</ss:http>
<ss:authentication-manager
xmlns:ss="http://www.springframework.org/schema/security" alias="authenticationManager">
<ss:authentication-provider>
<ss:jdbc-user-service data-source-ref="dataSource"
users-by-username-query="
select username, password, enabled
from users where username=?"
authorities-by-username-query="
select u.username, ur.authority from users u, authorities ur
where u.id = ur.user_id and u.username =? " />
</ss:authentication-provider>
</ss:authentication-manager>
</spring:beans>
<jdbc:postgresql-data-source name="postgreName"
user="anyuser" password="0123456" url="jdbc:postgresql://127.0.0.1/anyservice"
transactionIsolation="UNSPECIFIED" doc:name="PostgreSQL Data Source">
</jdbc:postgresql-data-source>
<jdbc:connector name="jdbcConnector" dataSource-ref="postgreName"
validateConnections="false" queryTimeout="10" pollingFrequency="10000"
doc:name="Database">
<reconnect frequency="3000" blocking="false" />
<jdbc:query key="anydb" value="insert into inbound_msgs (ip_from, request_size, modified_request_size, timestamp, url)
values (
#[groovy: return message.getInboundProperty('MULE_REMOTE_CLIENT_ADDRESS').toString()],
#[groovy: return message.getInboundProperty('http.request.old').toString().length()],
#[groovy: return message.getInboundProperty('http.request').toString().length()],
now(),
#[groovy: return message.getInboundProperty('http.context.uri').toString()]);">
</jdbc:query>
</jdbc:connector>
<scripting:transformer name="noopLoggingTransformer"
doc:name="Script">
<scripting:script engine="groovy">
def props = [:]
//props['User-Agent'] = message.getProperty('User-Agent', org.mule.api.transport.PropertyScope.INBOUND)
props['MULE_REMOTE_CLIENT_ADDRESS'] =
message.getProperty('MULE_REMOTE_CLIENT_ADDRESS',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.context.uri'] = message.getProperty('http.context.uri',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request.old'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
muleContext.client.dispatch('vm://log-request.in', payload, props)
message
</scripting:script>
</scripting:transformer>
<flow name="log-request" doc:name="log-request">
<vm:inbound-endpoint path="log-request.in"
doc:name="VM" />
<jdbc:outbound-endpoint exchange-pattern="one-way"
queryKey="anydb" responseTimeout="10000" queryTimeout="10"
connector-ref="jdbcConnector" doc:name="Persist raw message">
</jdbc:outbound-endpoint>
</flow>
<pattern:web-service-proxy name="logBypass" doc:name="logBypass">
<inbound-endpoint address="http://localhost/services/logBypass" exchange-pattern="request-response" transformer-refs="noopLoggingTransformer">
<mule-ss:http-security-filter realm="mule-realm"></mule-ss:http-security-filter>
</inbound-endpoint>
<outbound-endpoint address="http://targetServer/logBypass" exchange-pattern="request-response"/>
</pattern:web-service-proxy>
Mule 版本 3.4.0
几天后我找到了解决问题的方法:
与:
<scripting:transformer name="noopLoggingTransformer"
doc:name="Script">
<scripting:script engine="groovy">
import org.apache.commons.codec.binary.Base64
def props = [:]
//props['User-Agent'] = message.getProperty('User-Agent', org.mule.api.transport.PropertyScope.INBOUND)
props['MULE_REMOTE_CLIENT_ADDRESS'] =
message.getProperty('MULE_REMOTE_CLIENT_ADDRESS',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.context.uri'] = message.getProperty('http.context.uri',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request.old'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
def headerData = message.getProperty('http.headers',org.mule.api.transport.PropertyScope.INBOUND)
def userName = ""
if (headerData["Authorization"] != null) {
def security = headerData["Authorization"].split(" ")
def bytes = security[1].bytes
Base64 coder = new Base64()
def decodedData = coder.decode(bytes)
def userNamePwd = new String(decodedData)
def userNameSplit = userNamePwd.split(":")
userName = userNameSplit[0]
}
props['userName'] = userName
def method = ""
if (headerData["SOAPAction"] != null) {
method = headerData["SOAPAction"]
}
props['method'] = method
muleContext.client.dispatch('vm://log-request.in', payload, props)
message
</scripting:script>
</scripting:transformer>
那个和问题中的代码将在 Mule 3.4.0 上完美运行 请记住更改数据库以适应您的需要。