< Day Day Up > |
Security tokens are security artifacts included in the message that are typically used for authentication or authorization purposes. Understanding tokens is relatively straightforward when you see examples such as username/password, an X.509 certificate, or an SAML assertion. Many different token types have been defined, and the WS-Security specification is extensible enough to enable new types of tokens as they emerge. You might think that security tokens would look something like Listing 7.2. Listing 7.2. Assumed WS-Security Security Token Structure<wsse:SecurityToken> <username>fred</username> <password>password</password> </wsse:SecurityToken> This is not the case; no SecurityToken wrapper element is defined in the WS-Security XML Schema. The wrapper element for security tokens varies by the type of security token. Tokens are generally broken out into three types: UsernameToken , BinaryToken , and XML Token. UsernameToken and BinaryToken have a wrapping element to represent them; however, XML Tokens tend to have their own unique elements based on the type of token they represent. For example, an SAML token is represented by an Assertion element. The following sections describe each of these types of security tokens in turn . Note XML Tokens were not specified in the WS-Security 1.0 specification; only UsernameToken and BinarySecurityToken were represented. A follow-on specification called WS-Security Profile for XML Tokens (http://msdn.microsoft.com/ webservices /default.aspx?pull=/library/en-us/dnglobspec/html/WS-Security-xml-tokens.asp) came out in late August 2002. This strategy of breaking out different types of tokens into their own specification was continued in the OASIS committee, and all the different token types have been split into their own specification documents. UsernameTokenNo security mechanism would be complete without the old standby username/password option. We will try to forget that this mechanism is replete with problems ”for example, simple, hackable passwords; or complex and therefore written-down passwords ”and try to comment objectively. Security is often about making cost-benefit decisions, and in some situations, this is the appropriate security strategy. For example, you might consider using a username/password strategy if you have limited value or limited risk data and a user population unwilling or unable to use the more sophisticated authentication options such as X.509 client certificates. A peculiar issue about putting username and password into a secured SOAP message is that one of the major objectives of using WS-Security is to have the message be self-protecting . Having a clear-text password persisted with the message defeats this purpose. You can employ strategies to move past this issue, but these strategies are not always available; therefore, additional vulnerabilities could be introduced if you are not careful. The following sections further explain what we mean. UsernameToken with Clear-Text PasswordListing 7.3 shows the basic UsernameToken from the WS-Security specification. [4] This example shows a Username token with a WS-Security header.
Listing 7.3. The Basic <UsernameToken> from the WS-Security Specification <S:Envelope> <S:Header> ... <wsse:Security> <wsse:UsernameToken> <wsse:Username>Zoe</wsse:Username> <wsse:Password> ILoveDogs </wsse:Password> </wsse:UsernameToken> </wsse:Security> ... </S:Header> ... </S:Envelope> You will notice, of course, that the password is right out in the clear. Ouch. That's not very secure. If you choose to use such an approach, you should at least consider running under SSL (or some other secure transport strategy) so that the message will be encrypted during transmission. This approach would be similar to combining HTTP basic authentication, which sends the username and password in the clear, with SSL. However, at least transport security does not represent itself as securing the message, and it is still hard to justify having the result of message security being applied and ending up with a clear-text password. UsernameToken with PasswordDigestWS-Security provides an alternative to the clear-text password approach. This approach, called PasswordDigest , is a viable alternative as long as you already have the clear-text password on both sides of the exchange. The process involves hashing some random information (more specifics on this topic in the next section, "Username PasswordDigest Algorithm") with the password and then sending it in the UsernameToken . The same process then occurs on the receiving end. The issue here is getting the password in clear text on both sides of the exchange. In the Web application world, asking a user for a password is usually a straightforward process. The user is usually present to provide it, so you do not have to store it anywhere . If you have to store a password, it is common practice to store the password as a hashed value. When someone provides the password, you hash the password provided and compare the just-computed digest to the digest previously stored. Remember, hashes have the extremely valuable characteristic of being one way, so you cannot get from the stored digest back to the clear-text password. If, on the client or on the server side, the password has been stored as a hash value, the PasswordDigest option will not work for you because you need access to the password directly. Actually, in one situation, this is not completely true. If you know that both sides of the exchange have used the same hashing algorithm (SHA1, for instance), you can apply the algorithm described in the next section, substituting the digest itself for the password. In essence, the hash becomes the password. Let's go through the details of the algorithm and then look at an example. Username PasswordDigest AlgorithmTo use the PasswordDigest type of UsernameToken , you hash together three items: a time stamp, a nonce, and the password itself:
To summarize, as a client calling a Web service that requires a UsernameToken of type PasswordDigest , you (with help from your development tools most likely) will need to acquire a current time stamp, concatenate it to a unique nonce, and then concatenate them to the password. This combination then has the SHA1 algorithm applied, and you obtain the resulting digest password. You must then provide the information the server needs to repeat the process on the server side, which means the time stamp and nonce that were used are included in the UsernameToken . The PasswordDigest version of a UsernameToken looks like Listing 7.4. [5]
Listing 7.4. The PasswordDigest Version of a UsernameToken<wsse:Security> <wsse:UsernameToken xmlns:wsse=" http://www.docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-secext-1.0.xsd" xmlns:wsu=" http://www.docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-utility-1.0.xsd"> <wsse:Username>David Remy</wsse:Username> <wsse:PasswordType=" wsse:PasswordDigest "> D2A12DFE8D9F0C6BB82C89B091DF5C8A872F94DC </wsse:PasswordType> <wsse:Nonce>EFD89F06CCB28C89</wsse:Nonce> <wsu:Created>2001-10-13T09:00:00Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> When the server receives this UsernameToken , it repeats the process that the client uses to create the password digest. As mentioned previously, it is recommended that the server help prevent a replay attack by checking for freshness of the time stamp, for example, and, if the message is fresh enough, checking for a unique nonce. UsernameToken PasswordDigest SummaryIf you can be confident that clients of your Web service will have access to a shared secret in the same form that you have it, password digest is a viable, secure technique for authentication that comes with some protection for replay and man-in-the-middle attacks. The digest approach is still password based and has the problems of keeping the passwords secret and difficult to guess, but, from an ease-of-use perspective, this option has significant appeal . (Even in security-sensitive organizations, passwords are still used as the most common authentication scheme today.) BinarySecurityTokensA BinarySecurityToken can contain one of a few classes of binary credentials. The two classes of BinarySecurityToken s designated in WS-Security are X.509 Version 3 certificates and Kerberos tickets. Listing 7.5 shows the template for a BinarySecurityToken element. Listing 7.5. The Template for a <BinarySecurityToken> Element<wsse:BinarySecurityToken wsu:Id=... EncodingType=... ValueType=...> ...Binary Data ... <wsse:BinarySecurityToken/> Because BinarySecurityToken s are binary, you must specify an encoding type to represent them in XML. For example, you define an encoding type of Base-64 by specifying the EncodingType value of "wsse:Base64Binary" . The ValueType specifies what type of BinarySecurityToken is being used. Three ValueType s of BinarySecurityToken s are defined in the WS-Security specification: one is for X.509 Version 3 certificates, and the other two are related to Kerberos tickets. The following sections describe each of these types in turn. X.509 V3 CertificateAs you have learned elsewhere in this book, an X.509 Version 3 certificate is a digital container for the public key part of a public/private (asymmetric) key pair. A certificate authority that attests to the identity related to the public key signs this digital container. An X.509 certificate is public information that can be freely distributed, which leads to the following question when using an X.509 certificate as an authentication token: How can a freely available public piece of information be used for authentication? Having access to an X.509 certificate by itself does nothing to authenticate the identity of the SOAP message's sender. The answer here is to require what is typically called Proof of Possession . In the case of an X.509 certificate, Proof of Possession means a digital signature, which in the case of WS-Security means an XML Signature. If your Web service requires an X.509 certificate in a BinarySecurityToken , you will almost certainly want an XML Signature along with it so that you can verify that the sender has access to the corresponding private key. Remember that public key technology relies on the security concept of "something you have," which is the private key. Digital signatures are the way you prove that you have the private key that was used to digitally sign a message. If the message's receiver is able to successfully verify the XML Signature with the public key in the X.509 certificate, and the receiver trusts the certificate authority that verified the identity associated with the private key that signed the X.509 certificate, an X.509 certificate becomes a strong authentication mechanism. A BinarySecurityToken that contains an X.509 certificate contains a ValueType with the value of "wsse:X509V3" and, typically, an EncodingType of "wsse:Base64Binary" . Listing 7.6 shows an example of an X.509 certificate embedded in a BinarySecurityToken . Listing 7.6. An X.509 Certificate Embedded in a <BinarySecurityToken> <wsse:BinarySecurityToken Id="myX509Token" ValueType="wsse:X509v3" EncodingType="wsse:Base64Binary"> NIFEPzCCA9CrAwIBAgIQEmtJZc0 ... The rest of the X.509 base 64 data FExErTECA ... </wsse:BinarySecurityToken> We will further discuss including XML Signature in a Security header but now we need to make a point that relates to XML Signature and X.509 type BinarySecurityToken s. As you just learned, you will most likely have an XML Signature whenever you have a BinarySecurityToken of ValueType X509v3 . And, as you learned in Chapter 4, you can optionally specify the public key used to validat e an XML Signature within a KeyInfo block. In a WS-Security implementation, it is recommended that the KeyInfo block point to a BinarySecurityToken instead of using one of the alternative methods of specifying the verification key. For example, with the BinarySecurityToken shown in Listing 7.6, the related XML Signature would have the KeyInfo block shown in Listing 7.7. Listing 7.7. The <KeyInfo> for the <BinarySecurityToken> of Listing 7.6<ds:KeyInfo> <wsse:SecurityTokenReference> < wsse:Reference URI="#myX509Token"/> </wsse:SecurityTokenReference> </ds:KeyInfo> Kerberos TokensAs you read in Chapter 3, "The Foundations of Distributed Message-Level Security," Kerberos is a secret key technology “based network authentication protocol that involves a centralized Key Distribution Center (KDC). WS-Security makes it possible to pass a Kerberos ticket within a BinarySecurityToken . Two types of tickets are possible within Kerberos and, therefore, two ValueType s to represent them. When a Ticket Granting Ticket (TGT) is provided, the ValueType is wsse:KerberosV5TGT , and when a Service Ticket (ST) is present, the ValueType is wsse:KerberosV5ST . A TGT is independent of a particular service and is used more often for single sign-on purposes, whereas an ST is specific to a particular service. Listing 7.8 shows an example of a BinarySecurityToken containing a Kerberos ticket. Listing 7.8. A <BinarySecurityToken> Containing a Kerberos Ticket <wsse:BinarySecurityToken wsu:Id="myKerberosToken" ValueType=" wsse:Kerberosv5TGT " EncodingType="wsse:Base64Binary"> MIIEZzCCA9CgAwIBAgIQEmtJZc0 ... The rest of the Kerberos base 64 data here ... </wsse:BinarySecurityToken> X.509 certificates and Kerberos tickets are the two binary security token types that currently have bindings specified within WS-Security. It is certainly possible that new binary type tokens will emerge; however, most of the movement of new token types has been in the area of XML Tokens, which we discuss next. XML TokensIn the original WS-Security specification, only UsernameToken s and BinarySecurityToken s were described. A follow-on specification for XML tokens was published soon after. [6] One distinguishing characteristic of XML tokens is that they are not grouped together under one wrapping element the way BinarySecurityToken s are. With XML security tokens, each type of token has its own wrapping top-level element. The following sections describe the XML-type tokens so you can get a feel for how they work.
SAML TokensAs you learned in Chapter 6, "Portable Identity, Authentication, and Authorization," SAML is about representing identity, attributes, and/or authorization. In WS-Security, you can receive SAML assertion elements within the security header. Listing 7.9 shows the template for an SAML assertion. Listing 7.9. The Template for an SAML Assertion<saml:Assertion MajorVersion="1" MinorVersion="0" AssertionID="SecurityToken-ab12345" Issuer="yourIssuer" IssueInstant="2003-03-31T10:31:04.6118148-05:00" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"> ... </saml:Assertion> SAML assertions have a problem similar to X.509 certificates. The relying party must be able to determine that the sender ”or the identity being represented by the sender in the situation in which a third party is vouching for the sender ”really has proof of that sender's identity. Thus, the relying party must confirm the subject of the assertion by one of two methods: holder-of-key or sender-vouches . With the holder-of-key method, the sender ( requestor ) includes an XML Signature that contains a KeyInfo block with a SecurityTokenReference pointing to the SAML assertion. In this case, the SAML assertion contains key material ”for example, an X.509 certificate ”for verification of the signature in its ConfirmationMethod element. The other option for confirming the subject of the SAML assertion is sender-vouches . With sender-vouches , the sender of the message vouches for the assertion and will sign it. The major difference here is the target of the SAML assertions. With holder-of-key , the signature is typically created by the target of the SAML assertion; whereas with sender-vouches , the signature is created by a trusted third party that "vouches" for the SAML assertion. Listing 7.10 shows an example of a full SOAP message with an SAML token using the holder-of-key subject confirmation strategy. Listing 7.10. A Full SOAP Message with an SAML Token Using the holder-of-key <ConfirmationMethod><S:Envelope> <S:Header> <wsse:Security> <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" MajorVersion="1" MinorVersion="0" AssertionID="myAssertion" Issuer="www.yourIssuer.com" IssueInstant="2003-03-31T12:58:21.132Z"> <saml:Conditions NotBefore="2003-03-31T14:21:22.133Z" NotOnOrAfter="2003-03-31T16:02:11.123Z"/> <!-- An Authentication Assertion --> <saml:AuthenticationStatement AuthenticationMethod= "urn:oasis:names:tc:SAML:1.0:am:password" AuthenticationInstant="2003-03-31T14:21:22.000Z"> <saml:Subject> <saml:NameIdentifier NameQualifier="www.company.com" Format=""> uid=fred,ou=company,ou=unit,o=company.com </saml:NameIdentifier> <saml:SubjectConfirmation> <saml:ConfirmationMethod> urn:oasis:names:tc:SAML:1.0:cm:holder-of-key </saml:ConfirmationMethod> <ds:KeyInfo> <ds:KeyValue>. . .</ds:KeyValue> </ds:KeyInfo> </saml:SubjectConfirmation> </saml:Subject> </saml:AuthenticationStatement> <!-- An Attribute Assertion --> <saml:AttributeStatement> <saml:Attribute AttributeName="E-mail" AttributeNamespace= "http://www.company.com/attributes"> <saml:AttributeValue> fred@juno.com </saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement> <ds:Signature>...</ds:Signature> </saml:Assertion> <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#hmac-sha1"/> </ds:Reference> <ds:Reference URI="#msgBody"> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue> FxFtG0Qi3rPUr... </ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue> IKJwBVq81F32VjVRkF... </ds:SignatureValue> <ds:KeyInfo> <wsse:SecurityTokenReference> <wsse:Keyidentifier ValueType="saml:Assertion" myAssertion </wsse:Keyidentifier > </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> </wsse:Security> </S:Header> <S:Body wsu:Id="msgBody"> <StatusRequest xmlns="http://www.mycompany.com/order"> <OrderNumber>1234</OrderNumber> </StatusRequest> </S:Body> </S:Envelope> Listing 7.10 includes an authentication assertion and an attribute assertion ( asserting an email address for Fred). You will learn more about using XML Signatures to sign parts of a SOAP message later, but for now, notice that the XML Signature has as its KeyInfo a SecurityTokenReference that refers up to the SAML assertion. The SAML assertion wraps an AuthenticationStatement that specifies the ConfirmationMethod of holder-of-key ( urn:oasis:names:tc:SAML:1.0:cm:holder-of-key ) and contains its own KeyInfo that will contain the key material needed to validate the signature. The concept of using SAML tokens with SOAP messages is powerful. Many of the scenarios outlined in the SAML specification are ideally suited to Web service scenarios. By including an SAML assertion in the security header of the message, you allow the message body to address the transaction and the security header to contain metadata to facilitate the transaction. XrML TokensThe eXtensible Rights Markup Language (XrML) is an XML syntax for Digital Rights Management (DRM), which is described in detail in Chapter 9, "Trust, Access Control, and Rights for Web Services." A binding for XrML is specified for WS-Security in which a license element can be included in the header. XrML has a similar problem to both X.509 certificates and SAML tokens with respect to confirming the claims a subject represented in the license. In XrML, you confirm these claims by including an XML Signature that points back to information in the license that provides the key material necessary to validate the XML Signature and therefore prove that the claim is legitimately bound to the message. Listing 7.11 shows an example of an XrML license in the security header of a SOAP message. Listing 7.11. An XrML License in the WS-Security Header of a SOAP Message<S:Envelope> <S:Header> <wsse:Security> <r:license licenseId="urn:foo:SecurityToken:ab12345"> <r:grant> <r:keyHolder> <r:info> <ds:KeyValue>...</ds:KeyValue> </r:info> </r:keyHolder> <r:possessProperty/> <sx:commonName>John Doe</sx:commonName> </r:grant> <r:issuer> <ds:Signature>...</ds:Signature> </r:issuer> </r:license> <ds:Signature> <ds:SignedInfo> ... <ds:Reference URI="#msgBody" > <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue>...</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>...</ds:SignatureValue> <ds:KeyInfo> <wsse:SecurityTokenReference> <wsse:Reference URI="urn:foo:SecurityToken:ab12345" ValueType="r:license" /> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> </wsse:Security> </S:Header> <S:Body wsu:Id="msgBody" > <PictureRequest xmlns="http://www.myCompany.com/pics"> <Picture format="image/gif"> AxE1TrsRGGH... </Picture> </PictureRequest> </S:Body> </S:Envelope> As you can see in Listing 7.11, similar to both the X.509 and SAML examples, an XML Signature references the SOAP message body. The KeyInfo contains a SecurityTokenReference , which in turn contains a Reference pointing up to the license security token identified by the licenseId that matches the URI. XCBF TokensXML Common Biometric Format (XCBF) tokens are also specified as a type of security token that can be included in a WS-Security header. We do not describe these types of tokens in detail, but you can view the WS-Security XCBF binding specification at the OASIS Security TC site (http://www.oasis-open.org/committees/wss/documents/WSS-XCBF.pdf). The main point here is to show the flexibility of WS-Security to add new types of tokens by simply adding binding specifications. Referencing Security TokensAs you have seen in the examples just listed, one of the problems related to security tokens is how to reference them from other places. Whereas XML uses Key or Id as an identifier, the different types of security tokens can each have different strategies for unique identifiers. For example in XrML, licenseId is the most appropriate unique identifier. To address this issue, WS-Security introduces the SecurityTokenReference element as a standard way to refer to security tokens regardless of their format. Within a SecurityTokenReference , you can refer to a token in three ways: using direct elements, key identifiers, or key names. A direct SecurityTokenReference simply points to the security token via a URI that optionally provides a hint, in a ValueType attribute, of what type of security token is being pointed to. A template for this approach is shown in Listing 7.12. Listing 7.12. The Template for a Direct <SecurityTokenReference><wsse:SecurityTokenReference wsu:Id="..."> <wsse:Reference URI="..." ValueType="..."/> </wsse:SecurityTokenReference> An example of a direct SecurityTokenReference is shown in Listing 7.13. Listing 7.13. An Example of a Direct <SecurityTokenReference><wsse:SecurityTokenReference xmlns:wsse=" http://www.docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-secext-1.0.xsd"> <wsse:Reference URI="http://www.company.com/remy#X509token" ValueType="wsse:X509v3"/> </wsse:SecurityTokenReference> Alternatively, you can use a key identifier strategy in which you include an appropriate identifier of the key in the element. The key identifier approach allows for the use of a completely unique identifier based on the specific token type. Listing 7.14 shows a template for a <KeyIdentifier> -based SecurityTokenReference . Listing 7.14. Template for a <KeyIdentifier> -Based <SecurityTokenReference> <wsse:SecurityTokenReference> <wsse:KeyIdentifier wsu:Id="..." ValueType="..." EncodingType="..."> ... Value of Key Identifier here ... </wsse:KeyIdentifier> </wsse:SecurityTokenReference> An example of such a <SecurityTokenReference> is shown is Listing 7.15. Listing 7.15. An example of a <KeyIdentifier>- Based <SecurityTokenReference><wsse:SecurityTokenReference> <wsse:KeyIdentifier ValueType="wsse:X509v3"> uTHyQBrcgFu4xmo14mD/iYgyyIg= </wsse:KeyIdentifier> </wsse:SecurityTokenReference> You also can use a ds:KeyName element to refer to a security token by some arbitrary name of the key; however, the specification discourages this approach because the KeyName is not necessarily unique and could therefore match multiple security tokens. These three types of references refer to a security token that is outside the SecurityTokenReference itself. Another option is to embed the security token directly into the SecurityTokenReference , as shown in Listing 7.16. Listing 7.16. An Example of Embedding the Security Token Directly into the <SecurityTokenReference><wsse:SecurityTokenReference> <wsse:Embedded> <wsse:BinarySecurityToken ValueType="wsse:X509v3" EncodingType="wsse:Base64Binary" wsu:Id="X509Token"> MIIEZzCCA9CgAwIBAgIQEmtJZc0rqrKh5i... </wsse:BinarySecurityToken> </wsse:Embedded> </wsse:SecurityTokenReference> One common place you will see a SecurityTokenReference is a KeyInfo block within an XML Signature in the security header. It is also possible to have SecurityTokenReference elements directly in the security header. At this point, we've completed our coverage of security tokens in WS-Security. Over time, new types of security tokens will emerge and should fit into the flexible WS-Security specification. Already, the types of security tokens envisioned will provide powerful identification and authorization technology not only at the enterprise level, but also for the broader Internet. |
< Day Day Up > |