Mule ESB 学习笔记(16)CXF SOAP基于SAML的验证的配置

mule的配置

<mule xmlns:core="http://www.mulesoft.org/schema/mule/core" xmlns="http://www.mulesoft.org/schema/mule/core"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:spring="http://www.springframework.org/schema/beans"
    xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf"
    xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:http="http://www.mulesoft.org/schema/mule/http"
    xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd 
http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd 
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd " version="EE-3.3.0">
    <spring:beans>
        <spring:bean id="Bean" name="samlCustomValidator" class="com.mulesoft.mule.soap.security.SAMLCustomValidator"/>
    </spring:beans>

    
    <flow name="SamlTokenServiceFlow" doc:name="SamlTokenServiceFlow">
        <http:inbound-endpoint address="http://localhost:63084/services/saml" exchange-pattern="request-response" doc:name="HTTP Inbound Endpoint"/>
        <cxf:jaxws-service serviceClass="com.mulesoft.mule.soap.security.Greeter" doc:name="Secure SAMLToken service">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="SAMLTokenUnsigned Timestamp"/>
                </cxf:ws-config>
                <cxf:ws-custom-validator>
                    <cxf:saml2-token-validator ref="samlCustomValidator"/>
                </cxf:ws-custom-validator>
            </cxf:ws-security>
        </cxf:jaxws-service>
        <component class="com.mulesoft.mule.soap.security.GreeterService" doc:name="Greeter Service"/>
    </flow>

    <flow name="SignedSamlTokenServiceFlow" doc:name="SignedSamlTokenServiceFlow">
        <http:inbound-endpoint address="http://localhost:63084/services/signedsaml" exchange-pattern="request-response" doc:name="HTTP Inbound Endpoint"/>
        <cxf:jaxws-service serviceClass="com.mulesoft.mule.soap.security.Greeter" doc:name="Secure SAMLToken Signed service">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="SAMLTokenUnsigned Signature"/>
                    <cxf:property key="signaturePropFile" value="wssecurity.properties" />
                </cxf:ws-config>
                <cxf:ws-custom-validator>
                    <cxf:saml2-token-validator ref="samlCustomValidator"/>
                </cxf:ws-custom-validator>
            </cxf:ws-security>
        </cxf:jaxws-service>
        <component class="com.mulesoft.mule.soap.security.GreeterService" doc:name="Greeter Service"/>
    </flow>
</mule>

 

 

package com.mulesoft.mule.soap.security;

import java.io.IOException;
import java.util.Collections;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.saml.ext.SAMLCallback;
import org.apache.ws.security.saml.ext.bean.AuthenticationStatementBean;
import org.apache.ws.security.saml.ext.bean.SubjectBean;
import org.apache.ws.security.saml.ext.builder.SAML2Constants;
import org.opensaml.common.SAMLVersion;

/**
 *  Callback handler that populates a SAML 2.0 assertion based on the SAML properties file
 */
public class SAMLCallbackHandler implements CallbackHandler {

    private String subjectName;
    private String subjectQualifier;
    private String confirmationMethod;

    public SAMLCallbackHandler()
    {
        subjectName = "AllowGreetingServices";
        subjectQualifier = "www.example.com";
        confirmationMethod = SAML2Constants.CONF_SENDER_VOUCHES;
    }

    public void handle(Callback[] callbacks)
            throws IOException, UnsupportedCallbackException
    {
        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof SAMLCallback) {
                SAMLCallback callback = (SAMLCallback) callbacks[i];
                callback.setSamlVersion(SAMLVersion.VERSION_20);
                SubjectBean subjectBean =
                        new SubjectBean(
                                subjectName, subjectQualifier, confirmationMethod
                        );
                callback.setSubject(subjectBean);
                createAndSetStatement(null, callback);
            } else {
                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
            }
        }
    }

    private void createAndSetStatement(SubjectBean subjectBean, SAMLCallback callback) {
        AuthenticationStatementBean authBean = new AuthenticationStatementBean();
        if (subjectBean != null) {
            authBean.setSubject(subjectBean);
        }
        authBean.setAuthenticationMethod("Password");
        callback.setAuthenticationStatementData(Collections.singletonList(authBean));
    }

}

 

 

import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.handler.RequestData;
import org.apache.ws.security.saml.ext.AssertionWrapper;
import org.apache.ws.security.saml.ext.OpenSAMLUtil;
import org.apache.ws.security.validate.Credential;
import org.apache.ws.security.validate.SamlAssertionValidator;

public class SAMLCustomValidator extends SamlAssertionValidator
{
    @Override
    public Credential validate(Credential credential, RequestData data) throws WSSecurityException
    {
        Credential returnedCredential = super.validate(credential, data);
        //
        // Do some custom validation on the assertion
        //
        AssertionWrapper assertion = credential.getAssertion();
        if (!"self".equals(assertion.getIssuerString()))
        {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
        }

        if (assertion.getSaml2() == null)
        {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
        }

        String confirmationMethod = assertion.getConfirmationMethods().get(0);
        if (confirmationMethod == null)
        {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
        }
        if (!OpenSAMLUtil.isMethodSenderVouches(confirmationMethod))
        {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
        }

        if(!"AllowGreetingServices".equals(assertion.getSaml2().getSubject().getNameID().getValue()))
        {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
        }

        return returnedCredential;
    }



}

 

 

服务端:

import org.mule.api.MuleContext;
import org.mule.api.MuleException;
import org.mule.api.context.MuleContextFactory;
import org.mule.config.spring.SpringXmlConfigurationBuilder;
import org.mule.context.DefaultMuleContextFactory;

public class MuleServerApp {
  public static void main(String[] args) throws MuleException {
	  String configFile = "mule-config.xml";
      System.setProperty("mule.verbose.exceptions","true");
      String[] configFileArr = new String[] {configFile };
      MuleContextFactory muleContextFactory = new DefaultMuleContextFactory();
      MuleContext muleContext = muleContextFactory
              .createMuleContext(new SpringXmlConfigurationBuilder(configFileArr));
      muleContext.start();
  }
}

 

客户端测试:

public class MuleSecureClient
{
    public static void main(String[] args) throws Exception
    {
        Greeter service = createService("http://localhost:63084/services/saml?wsdl",
            getSamlTokenProps("SAMLTokenUnsigned Timestamp", "saml.properties"));
        System.out.println(service.greet("Mule"));
        
        
        service = createService("http://localhost:63084/services/signedsaml?wsdl",
                                        getSignedSamlTokenProps("SAMLTokenSigned", "saml.properties"));
        System.out.println(service.greet("Mule"));
    }    

    protected static Map<String, Object> getSamlTokenProps(String action, String propertiesFile)
    {
        Map<String, Object> wss4jProps = new HashMap<String, Object>();
        wss4jProps.put("action", action);
        wss4jProps.put("samlPropFile", propertiesFile);
        SAMLCallbackHandler samlCallbackHandler = new SAMLCallbackHandler();
        wss4jProps.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
        return wss4jProps;
    }

    protected static Map<String, Object> getSignedSamlTokenProps(String action, String propertiesFile)
    {
        Map<String, Object> wss4jProps = new HashMap<String, Object>();
        wss4jProps.put("action", action);
        wss4jProps.put("samlPropFile", propertiesFile);
        wss4jProps.put("signatureKeyIdentifier", "DirectReference");
        wss4jProps.put("user", "joe");
        wss4jProps.put("passwordCallbackClass", PasswordCallback.class.getName());
        wss4jProps.put(WSHandlerConstants.SAML_CALLBACK_REF, new SAMLCallbackHandler());
        return wss4jProps;
    }
    
    public static Greeter createService(String url, Map<String, Object> wss4jProps)
    {
        URL wsdlDocumentLocation;
        try
        {
            wsdlDocumentLocation = new URL(url);
        }
        catch (MalformedURLException e)
        {
            throw new RuntimeException("Invalid test definition", e);
        }
        QName serviceName = new QName("http://security.soap.mule.mulesoft.com/", "GreeterService");

        Service dynService = Service.create(wsdlDocumentLocation, serviceName);
        Greeter service = dynService.getPort(Greeter.class);
        Client client = ClientProxy.getClient(service);

        if (wss4jProps != null)
        {
            client.getOutInterceptors().add(new WSS4JOutInterceptor(wss4jProps));
        }

        return service;
    }
    
}


 

你可能感兴趣的:(SOA,mule,ESB,CXF webservice,SAML 认证)