Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-3635

WS-Trust SPNego (WCF message level spnego)

    Details

    • Type: New Feature
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.3.5
    • Fix Version/s: 2.4.7, 2.5.3
    • Component/s: WS-* Components
    • Labels:
      None
    • CXF Fields:
      Blocked on External

      Description

      We have spent time implementing SPNego over WS-Trust support for CXF and wish to submit it for possible inclusion in CXF itself. (Or at least as an example for others to follow) This was implemented so we could use the webservice of MS CRM 2011 when configured for 'on-premise' security, although I think WCF 4.0 uses this type of security by default if you explicitly change it. So I'm sure this functionality would be useful to others.

      1. cxf-3635-pluggable.patch
        4 kB
        Colm O hEigeartaigh
      2. cxf-wstrust-spnego.zip
        14 kB
        Tom Schneider

        Issue Links

          Activity

          Hide
          schneidh Tom Schneider added a comment -

          Here's a quick snippet on how to configure this code:

          Client client = ClientProxy.getClient(port);
          Bus bus = ((EndpointImpl) client.getEndpoint()).getBus();
          PolicyInterceptorProviderRegistry pipr = bus
          .getExtension(PolicyInterceptorProviderRegistry.class);
          AssertionBuilderRegistry reg = bus.getExtension(AssertionBuilderRegistry.class);
          client.getEndpoint().getEndpointInfo().setProperty("spnego.username", <username>);
          client.getEndpoint().getEndpointInfo().setProperty("spnego.password", <password>);
          client.getEndpoint().getEndpointInfo().setProperty("spnego.spn", <kerberos-spn>);
          client.getEndpoint().getEndpointInfo().setProperty("spnego.jass.client", <jass-clientname>);
          reg.register(new SpnegoContextTokenBuilder());
          pipr.register(new SpnegoContextTokenInterceptorProvider());

          Show
          schneidh Tom Schneider added a comment - Here's a quick snippet on how to configure this code: Client client = ClientProxy.getClient(port); Bus bus = ((EndpointImpl) client.getEndpoint()).getBus(); PolicyInterceptorProviderRegistry pipr = bus .getExtension(PolicyInterceptorProviderRegistry.class); AssertionBuilderRegistry reg = bus.getExtension(AssertionBuilderRegistry.class); client.getEndpoint().getEndpointInfo().setProperty("spnego.username", <username>); client.getEndpoint().getEndpointInfo().setProperty("spnego.password", <password>); client.getEndpoint().getEndpointInfo().setProperty("spnego.spn", <kerberos-spn>); client.getEndpoint().getEndpointInfo().setProperty("spnego.jass.client", <jass-clientname>); reg.register(new SpnegoContextTokenBuilder()); pipr.register(new SpnegoContextTokenInterceptorProvider());
          Hide
          coheigea Colm O hEigeartaigh added a comment -

          Hi Tom,

          Is it possible to re-use the existing STSClient, instead of duplicating the code for the SPNEGO case? What were the reasons behind this?

          Thanks,

          Colm.

          Show
          coheigea Colm O hEigeartaigh added a comment - Hi Tom, Is it possible to re-use the existing STSClient, instead of duplicating the code for the SPNEGO case? What were the reasons behind this? Thanks, Colm.
          Hide
          schneidh Tom Schneider added a comment -

          I think there were enough differences that I couldn't get it to work without making changes. It's definitely something I wanted to look into, but it was quicker to copy and make changes to the existing STSClient just to get things going. I do think with some refactoring the built-in STSClient could be used for these types of requests.

          Show
          schneidh Tom Schneider added a comment - I think there were enough differences that I couldn't get it to work without making changes. It's definitely something I wanted to look into, but it was quicker to copy and make changes to the existing STSClient just to get things going. I do think with some refactoring the built-in STSClient could be used for these types of requests.
          Hide
          coheigea Colm O hEigeartaigh added a comment -

          Hi Tom,

          I have finally gotten around to reviewing this patch and have committed a fairly extensively modified version of it to trunk (it's a bit more robust and shares some code with the SecureConversation code, which does something very similar):

          http://svn.apache.org/viewvc?view=revision&revision=1221366

          I have also added support for the STS side of the SPNEGO exchange (solely for testing purposes), and added some system tests based around it. The System tests are here:

          http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/spnego/SpnegoTokenTest.java?view=markup

          The client configuration is here:

          http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/spnego/client/client.xml?view=markup

          The server configuration is here:

          http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/spnego/server/server.xml?view=markup

          and the WSDL is here:

          http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/spnego/DoubleItSpnego.wsdl?view=markup

          The tests are @Ignored as they rely on a KDC. I have not tested this with WCF, only CXF, and so it would be great if you could modify the system test to use your test credentials and let me know if it works or not.

          Thanks,

          Colm.

          Show
          coheigea Colm O hEigeartaigh added a comment - Hi Tom, I have finally gotten around to reviewing this patch and have committed a fairly extensively modified version of it to trunk (it's a bit more robust and shares some code with the SecureConversation code, which does something very similar): http://svn.apache.org/viewvc?view=revision&revision=1221366 I have also added support for the STS side of the SPNEGO exchange (solely for testing purposes), and added some system tests based around it. The System tests are here: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/spnego/SpnegoTokenTest.java?view=markup The client configuration is here: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/spnego/client/client.xml?view=markup The server configuration is here: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/spnego/server/server.xml?view=markup and the WSDL is here: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/spnego/DoubleItSpnego.wsdl?view=markup The tests are @Ignored as they rely on a KDC. I have not tested this with WCF, only CXF, and so it would be great if you could modify the system test to use your test credentials and let me know if it works or not. Thanks, Colm.
          Hide
          schneidh Tom Schneider added a comment -

          Great, I'll try to find some time to test this after the new year. I'll let you know if I run into any issues.
          Tom

          Show
          schneidh Tom Schneider added a comment - Great, I'll try to find some time to test this after the new year. I'll let you know if I run into any issues. Tom
          Hide
          schneidh Tom Schneider added a comment -

          Everything worked great except for one minor change:

          In SpnegoClientAction.java, I had to change:
          GSSName gssService = gssManager.createName(serviceName, GSSName.NT_HOSTBASED_SERVICE);
          To:
          GSSName gssService = gssManager.createName(serviceName, null);

          Without this change, I wasn't getting a kerberos ticket back.

          One other issue I had was that the signature verification is failing when the SOAP response from the server is a fault. (For example, if I ask for a contact id that doesn't exist) We worked around this issue in our code by ignoring signature validation failures. Not sure if this is a CXF or a WCF issue... I can provide more details if needed.

          I also think some good documentation around this would be good. It took me quite a while to figure out how to configure this, even with the help of your unit tests. I'd like to put something together before I forget everything.

          Show
          schneidh Tom Schneider added a comment - Everything worked great except for one minor change: In SpnegoClientAction.java, I had to change: GSSName gssService = gssManager.createName(serviceName, GSSName.NT_HOSTBASED_SERVICE); To: GSSName gssService = gssManager.createName(serviceName, null); Without this change, I wasn't getting a kerberos ticket back. One other issue I had was that the signature verification is failing when the SOAP response from the server is a fault. (For example, if I ask for a contact id that doesn't exist) We worked around this issue in our code by ignoring signature validation failures. Not sure if this is a CXF or a WCF issue... I can provide more details if needed. I also think some good documentation around this would be good. It took me quite a while to figure out how to configure this, even with the help of your unit tests. I'd like to put something together before I forget everything.
          Hide
          coheigea Colm O hEigeartaigh added a comment -

          Hi Tom,

          Great, thanks for trying it out.

          > Without this change, I wasn't getting a kerberos ticket back.

          Do you have any thoughts on what the correct default should be? If I change it to "null" then my local test-case fails. I guess I could make it configurable whether it is a host based service or not?

          > One other issue I had was that the signature verification is failing when the SOAP response from the server is a
          > fault... I can provide more details if needed.

          Yes, please do.

          > I also think some good documentation around this would be good.

          Once we reach agreement and the test-case is working then I can write something up.

          Colm.

          Show
          coheigea Colm O hEigeartaigh added a comment - Hi Tom, Great, thanks for trying it out. > Without this change, I wasn't getting a kerberos ticket back. Do you have any thoughts on what the correct default should be? If I change it to "null" then my local test-case fails. I guess I could make it configurable whether it is a host based service or not? > One other issue I had was that the signature verification is failing when the SOAP response from the server is a > fault... I can provide more details if needed. Yes, please do. > I also think some good documentation around this would be good. Once we reach agreement and the test-case is working then I can write something up. Colm.
          Hide
          schneidh Tom Schneider added a comment -

          The following also worked for me:
          GSSName gssService = gssManager.createName(serviceName, GSSName.NT_USER_NAME);
          which makes sense since I'm using an active directory username and password to authenticate with Kerberos. I guess this has to be configurable since we can't assume an initial authentication mechanism. Another option might be to allow a user to pass in their own SpnegoClientAction like I've currently doing with the NamePasswordCallback. (i.e. the ws-security.callback-handler property) That would provide the most flexibility.

          You're too late for the documentation, I already created an example for CRM 2011 and added a link on the CXF wiki:
          http://groovyjava-tom.blogspot.com/2012/01/cxf-and-ms-crm-2011.html

          I'll try to put together a unit test for the working and non-working signature validation.

          Show
          schneidh Tom Schneider added a comment - The following also worked for me: GSSName gssService = gssManager.createName(serviceName, GSSName.NT_USER_NAME); which makes sense since I'm using an active directory username and password to authenticate with Kerberos. I guess this has to be configurable since we can't assume an initial authentication mechanism. Another option might be to allow a user to pass in their own SpnegoClientAction like I've currently doing with the NamePasswordCallback. (i.e. the ws-security.callback-handler property) That would provide the most flexibility. You're too late for the documentation, I already created an example for CRM 2011 and added a link on the CXF wiki: http://groovyjava-tom.blogspot.com/2012/01/cxf-and-ms-crm-2011.html I'll try to put together a unit test for the working and non-working signature validation.
          Hide
          coheigea Colm O hEigeartaigh added a comment -

          Hi Tom,

          I've added the ability to make the SpnegoClientAction and SpnegoServiceAction interfaces pluggable in WSS4J:

          https://issues.apache.org/jira/browse/WSS-332?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel#issue-tabs

          I've attached a patch to this JIRA to use this functionality in CXF by setting a property. If you could review this and test it that would be great.

          Colm.

          Show
          coheigea Colm O hEigeartaigh added a comment - Hi Tom, I've added the ability to make the SpnegoClientAction and SpnegoServiceAction interfaces pluggable in WSS4J: https://issues.apache.org/jira/browse/WSS-332?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel#issue-tabs I've attached a patch to this JIRA to use this functionality in CXF by setting a property. If you could review this and test it that would be great. Colm.
          Hide
          schneidh Tom Schneider added a comment -

          Colm,
          What is the property I need to set? I looked through the source code of CXF and WSS4j, but I couldn't find it.
          Thanks,
          Tom

          Show
          schneidh Tom Schneider added a comment - Colm, What is the property I need to set? I looked through the source code of CXF and WSS4j, but I couldn't find it. Thanks, Tom
          Hide
          schneidh Tom Schneider added a comment -

          Colm,
          Disregard my last comment, I was confused because you did a checkin and there was a patch--I didn't see the attached patch at first.

          Yes, this is working for me now.
          Tom

          Show
          schneidh Tom Schneider added a comment - Colm, Disregard my last comment, I was confused because you did a checkin and there was a patch--I didn't see the attached patch at first. Yes, this is working for me now. Tom
          Hide
          schneidh Tom Schneider added a comment -

          As I was writing the unit test for the signature validation, I discovered that the decrypted XML for a fault isn't valid--the standard DOM parser refuses to parse it because one of the namespace prefixes is missing. So it looks like it's an issue on the CRM side. Once these changes are all checked in, I should be good.

          Show
          schneidh Tom Schneider added a comment - As I was writing the unit test for the signature validation, I discovered that the decrypted XML for a fault isn't valid--the standard DOM parser refuses to parse it because one of the namespace prefixes is missing. So it looks like it's an issue on the CRM side. Once these changes are all checked in, I should be good.

            People

            • Assignee:
              coheigea Colm O hEigeartaigh
              Reporter:
              schneidh Tom Schneider
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development