How would a php or java client authenticate if I'm using WCF w/ forms auth?

Deadly 提交于 2019-12-05 02:07:45

问题


I have a generic proof of concept WCF service that is using forms authentication to secure access. All works great when my client is .NET (vb code below)

Dim client As SupplierServiceClient = New SupplierServiceClient()
client.ClientCredentials.UserName.UserName = "xxxx@xxx.xx.xx"
client.ClientCredentials.UserName.Password = "password"

Dim SupplierList As List(Of Supplier) = client.GetSuppliers()

but as I want this to interop w/ anyone who can do SOAP 1.1/1.2 - how would a PHP or Java client connect?

My WCF web.config is listed below (fyi)

<system.serviceModel>
    <services>
        <service name="SampleApplicationWCF.Library.SupplierService" behaviorConfiguration="NorthwindBehavior">
            <endpoint address="" name="wsHttpSupplierService" contract="SampleApplicationWCF.Library.ISupplierService" binding="wsHttpBinding" bindingConfiguration="wsHttp"/>
            <endpoint address="https://server/SampleApplicationWCF/SupplierService.svc/Basic" name="basicHttpSupplierService" contract="SampleApplicationWCF.Library.ISupplierService" binding="basicHttpBinding" bindingConfiguration="basicHttp"/>
            <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
        </service>
    </services>
    <bindings>
        <wsHttpBinding>
            <binding name="wsHttp">
                <security mode="TransportWithMessageCredential">
                    <transport/>
                    <message clientCredentialType="UserName" negotiateServiceCredential="false" establishSecurityContext="true"/>
                </security>
            </binding>
        </wsHttpBinding>
        <basicHttpBinding>
            <binding name="basicHttp">
                <security mode="TransportWithMessageCredential">
                    <transport/>
                    <message clientCredentialType="UserName"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="NorthwindBehavior">
                <serviceMetadata httpGetEnabled="true"/>
                <serviceAuthorization principalPermissionMode="UseAspNetRoles"/>
                <serviceCredentials>
                    <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"/>
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

回答1:


I managed to authenticate a PHP client, but not without some effort. At first, I tried the following:

$header = new stdClass;
$credentials = new stdClass;
$credentials->Username="myuser";
$credentials->Password="mypass";
$header->UsernameToken = $credentials;

$securityNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
$client->__setSoapHeaders($securityNamespace, 'Security', $header);

It didn't work. It seems that PHP5 (v5.3.5 in my case) has a bug preventing the namespace prefix from appearing inside nested header tags. http://bugs.php.net/bug.php?id=48966
I ended up with:

<UsernameToken><Username>myuser</Username><Password>myuser</Password></UsernameToken>

instead of:

<o:UsernameToken><o:Username>myuser</o:Username><o:Password>myuser</o:Password></o:UsernameToken>

So, what I had to do was hardcoding the necessary XML in a variable. This is ugly but working:

$securityNamespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
$headerContent = "<o:Security xmlns:o=\"$securityNamespace\">
                    <o:UsernameToken>
                    <o:Username>myuser</o:Username>
                    <o:Password>mypass</o:Password>
                    </o:UsernameToken>
                </o:Security>";
$headerVar = new SoapVar($headerContent, XSD_ANYXML, null, null, null);
$header = new SoapHeader($securityNamespace, 'o:Security', $headerVar);
$client->__setSoapHeaders(array($header));

I hope it will be helpful to someone. Bye!




回答2:


Disclaimer: I am NOT a Java or PHP developer

By setting the UserName values on the client oject, you're telling WCF to ship that information across the wire as part of the SOAP header. Since SOAP is a very widely adopted standard, I'm sure there are libraries out there that will help you add that information to the SOAP message header. I would look for something that helps you consume services using WS-* and/or WS-I Basic Profile specfications.

Good luck.



来源:https://stackoverflow.com/questions/513330/how-would-a-php-or-java-client-authenticate-if-im-using-wcf-w-forms-auth

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!