cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Valeri <daval...@progress.com>
Subject RE: SAML and WS-Security
Date Fri, 12 Mar 2010 13:48:34 GMT
This looks like an issue with the contents of the unencrypted KeyInfo and WSS4J.  I have not
used symmetric keys much with WSS4J so I don't have a lot of experience here or with the XML
Enc spec.  From the error message, it sounds like WSS4J is expecting only an STR in the KeyInfo
where as I suspect you have key material embedded in a child of KeyInfo.  I would hunt around
on the WSS4J JIRA or try their mailing list if a quick look at the code doesn't reveal the
answer.

-----Original Message-----
From: John Hite [mailto:jhite@appsecinc.com] 
Sent: Wednesday, March 10, 2010 12:30 PM
To: users@cxf.apache.org
Subject: RE: SAML and WS-Security

I don't think that the problems I am having are with my STS or CXF's STSCLient. I can't seem
to get my target service to validate the Security header. I get the following exception.

org.apache.ws.security.WSSecurityException: An error was discovered processing the <wsse:Security>
header (WSSecurityEngine: EncryptedKey does not contain ds:KeyInfo/wsse:SecurityTokenReference)

I'm using a symmetric key, holder-of-key SAML Assertion. I can't find any reason in the specifications
as to why the EncryptedKey's KeyInfo element should contain a SecurityTokenReference. Am I
missing something? Have you experienced this problem before? Perhaps this is a wss4j bug?

Thanks,
John

Here's a SAML token for reference
<saml1:Assertion 
  AssertionID="SAML-12345" 
  IssueInstant="2010-03-10T16:31:01.831Z" 
  Issuer="http://www.example.com" 
  MajorVersion="1" 
  MinorVersion="1">
  <saml1:AttributeStatement>
    <saml1:Subject>
      <saml1:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
        user@example.com
      </saml1:NameIdentifier>
      <saml1:SubjectConfirmation>
        <saml1:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:holder-of-key</saml1:ConfirmationMethod>
        <ds:KeyInfo>
          <xenc:EncryptedKey>
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
              <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            </xenc:EncryptionMethod>
            <ds:KeyInfo>
              <ds:X509Data>
                <ds:X509Certificate>...</ds:X509Certificate>
              </ds:X509Data>
            </ds:KeyInfo>
            <xenc:CipherData>
              <xenc:CipherValue>...</xenc:CipherValue>
            </xenc:CipherData>
          </xenc:EncryptedKey>
        </ds:KeyInfo>
      </saml1:SubjectConfirmation>
    </saml1:Subject>
  </saml1:AttributeStatement>
  <ds:Signature>
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <ds:Reference URI="#SAML-12345">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"
/>
          <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
            <ec:InclusiveNamespaces PrefixList="ds saml1 xenc" />
          </ds:Transform>
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <ds:DigestValue>LmGqV2QdPPr7FS/pjhYOwy/CtUo=</ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>...</ds:SignatureValue>
    <ds:KeyInfo>
      <ds:X509Data>
        <ds:X509Certificate>...</ds:X509Certificate>
      </ds:X509Data>
    </ds:KeyInfo>
  </ds:Signature>
</saml1:Assertion>

-----Original Message-----
From: David Valeri [mailto:davaleri@progress.com] 
Sent: Sunday, March 07, 2010 9:26 AM
To: users@cxf.apache.org
Subject: RE: SAML and WS-Security

You can retrieve assertions for use in a CXF client in one of two ways: 

a) WSS4J SAMLIssuerFactory implementation.  You can use this approach if you manually configure
the WSS4JOutInterceptor and use the SAMLTokenSigned or SAMLTokenUnsigned actions.  WSS4J does
not provide you with an STS client and only provides a self-issuing implementation.  The API
they provide is fairly limited as well so if you need to funnel a lot of runtime info into
your factory implementation, customization will be needed.  The good thing about this approach
is that you can use the assertion returned from the factory as the signing token instead of
including a BST or otherwise referencing some key material (symmetric or asymmetric).

b) CXF WS-P and WS-SP based configuration and the STSClient.  The STSClient class can invoke
an STS by sending an RST request.  Support is not perfect in my experience so you may end
up customizing an STSClient for your specific scenario.  WS-T is incredibly flexible so having
the off-the-shelf client support your scenario if it is complex is not to be expected.  You
can specify a custom subclass of STSClient by setting the instance to a contextual property
in CXF using the key: SecurityConstants.STS_CLIENT.  See IssuedTokenInterceptorProvider for
full details of the use of this class.  The drawback to this approach is that CXF cannot yet
(to my knowledge which is a little behind the latest release) use the SAML Assertion as the
Initiator Token and can only use the assertion as a supporting token in addition to a BST
or other form of key material reference.  In this scenario, you should sign the assertion
into the message and use the holder-of-key confirmation method to confirm that the client
has proof of possession of the token.

Either of the above client side approaches is independent of the server side processing code.

You seem to be getting familiar with the specs so I don't see them affecting which above approach
you take.  If you wrote your own or customized some STS code, either approach above is going
to be accessible to you.

All of the above assumes that you have signatures and PKI in place, but you can accomplish
the same with STS generated keys as well if you don't have a PKI.  Hopefully this will get
you looking at the right code and provide you with enough info to determine which approach
is right for your scenario.

-----Original Message-----
From: John Hite [mailto:jhite@appsecinc.com] 
Sent: Friday, March 05, 2010 10:24 AM
To: users@cxf.apache.org
Subject: RE: SAML and WS-Security

Hi David,

Thank you for your reply. That interceptor will prove invaluable. I'll explain what I am trying
to do and answer your questions. Any advice you could give would be greatly appreciated.

I'm developing a set of services that may be distributed (i.e. running on different hosts
or different networks). These services should only accessible by authorized users, but I don't
want to have each service handle authenticating the user (in fact, it's possible that some
of the services may not be able to authenticate the user). To me this sounded like a good
scenario for WS-Trust. I can have an STS that the services trust handle authenticating users.
The STS would issue a signed SAML assertion to the user that can be used to access the other
services. Now, to answer your questions.

1) Do you intend to create your own assertions or retrieve them from a WS-Trust STS?
I intend to retrieve the assertions from the STS.

2) How familiar are you with WS-Trust?
I'm somewhat familiar with WS-Trust. It's still fairly new to me, but I've read through the
spec several times during the last week. I used the spec build my STS which is issuing a more
or less hard coded SAML token for now.

3) How familiar are you with SAML?
I'm less familiar with SAML than with WS-Trust. I've been reading the SAML Token Profile trying
to figure out which type of SAML assertion I need to issue from my STS.

4) Do you need to use the SAML assertion as the signing token (initiator token) in the message
or as a supporting/signed supporting token only?
I'm pretty sure I need to use the assertion as the signing token. If I am not mistaken, I
would need a trust relationship between the client and the web service if I was using the
SAML assertion as a supporting token. I can't have that. My client is pretty much not trusted.

I've understood the overall picture of WS-Trust, WS-Security, SAML, etc. for a while, but
only since last week have I been digging down into the details of the specifications and trying
to get things to work. It's been very frustrating trying to translate what I read in the spec
to an actual implementation using CXF. If I can get this done I'll try to contribute some
docs.

Thanks,
John

-----Original Message-----
From: David Valeri [mailto:davaleri@progress.com] 
Sent: Thursday, March 04, 2010 11:18 AM
To: users@cxf.apache.org
Subject: RE: SAML and WS-Security

I've accomplished this goal using a WSS4JInInterceptor as well as with PolicyBasedWSS4JInInterceptor
using CXF's WS-P support.

Regardless of the approach, the underlying WSS4J implementation code will unmarshall your
SAML assertion and make it available in the results.  WSS4J currently only supports OpenSAML
1.x so you are tied to SAML 1.x assertions.

The following code can be used to retrieve the parsed assertion in an interceptor after the
WSS4J interceptors complete:

        final Vector<WSSecurityEngineResult> samlResults = 
            new Vector<WSSecurityEngineResult>();

        // Note: when the outbound action is ST_SIGNED (SamlTokenSigned), the
        // results list is a ST_UNSIGNED because the SAML processor and
        // signature processors don't indicate if the assertion was used to
        // sign the message or not so you get signature results and ST_UNSIGNED
        // results even if the assertion was used to sign the message.
        WSSecurityUtil.fetchAllActionResults(wsHandlerResult.getResults(),
                WSConstants.ST_UNSIGNED, samlResults);

        final WSSecurityEngineResult result = samlResults.get(0);
        (SAMLAssertion) result.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);

Note that there can be more than one value in samlResults depending on the incoming message.

As far as I know, the CXF WS-P and WS-Trust support on the inbound side does not actually
validate the assertion against an STS or in any other manner.  I think you are on your own
as to the validation processing.  It should be noted that STSClient does contain code to make
the validation request, but I don't think it is currently integrated into the IssuedTokenInterceptor
(I'm a couple versions behind though).

If you also need to produce or acquire the SAML assertion in a CXF client, you should first
consider the following questions before you can decide which route is best for your scenario:
1) Do you intend to create your own assertions or retrieve them from a WS-Trust STS?
2) How familiar are you with WS-Trust?
3) How familiar are you with SAML?
4) Do you need to use the SAML assertion as the signing token (initiator token) in the message
or as a supporting/signed supporting token only?

Both CXF's WS-P/WS-T support and WSS4J's SAML issuing APIs have their limitations on the client
side so my recommendation depends on your objectives and comfort level more than anything.
 If you answer the above questions, I can provide you with some additional advice based on
my personal experiences.

-----Original Message-----
From: John Hite [mailto:jhite@appsecinc.com] 
Sent: Thursday, March 04, 2010 10:28 AM
To: users@cxf.apache.org
Subject: SAML and WS-Security

I'm trying to create a web service in CXF that is secured using WS-Security with SAML tokens.
Looking through the documentation, and briefly at the WSS4JInInterceptor, it appears that
this is not implemented. I want to modify WSS4JInInterceptor to handle SAML tokens. Can anyone
provide me with some information about how the WSS4JInInterceptor works to help me get started?
Also, I'm wondering if I need to modify the PolicyBasedWSS4JInInterceptor?

Thanks,
John

Mime
View raw message