如何在 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 上完美运行 请记住更改数据库以适应您的需要。