Showing posts with label Security. Show all posts
Showing posts with label Security. Show all posts

Monday, December 19, 2016

Single Sign On with SAML 2.0

Security Assertion Markup Language or SAML is the secure XML based communication standard for communicating identities, exchanging authentication and authorization data between parties. SAML is a specification which defines messages and their format, message encoding methods, message exchange protocols, and other recommendations. SAML addresses the primary use case of internet single sign on (SSO) which authenticates the user using a single login into the system and allows access to other affiliated systems without additional authentication. SAML thus eliminates multiple authentication credentials in multiple locations and reduces the number of the users being authenticated. It separates the security framework from platform architecture and specific vendor implementation. SAML involves three entities, the user, identity provider and server provider. The Identity Provider maintains a directory of users and an authentication mechanism to authenticate them. The Service Provider is the target application that a user tries to use.

SAML consists of six components as follows: assertions, protocols, bindings, profiles, metadata, authentication context. The components mainly enable to transfer secure information like identity, authentication, and authorization information between trusted entities.


SAML assertions contain identifying information made by a SAML authority. In SAML, there are three assertions: authentication, attribute, and authorization. Authentication assertion validates that the specified subject is authenticated by a particular means at a particular time and is made by a SAML authority called an identity provider. Attribute assertion contains specific information about the specified subject. And authorization assertion identifies what the specified subject is authorized to do.
SAML protocols define how SAML asks for and receives assertions and the structure and contents of SAML protocols are defined by the SAML-defined protocol XML schema.
SAML bindings define how SAML request-response message exchanges are mapped to communication protocols like Simple Object Access Protocol (SOAP). SAML works with multiple protocols including Hypertext Transfer Protocol (HTTP), Simple Mail Transfer Protocol (SMTP), File Transfer Protocol (FTP) and so on.
SAML profiles define constraints and/or extensions to satisfy the specific use case of SAML. For example, the Web SSO Profile details how SAML authentication assertions are exchanged between entities and what the constraints of SAML protocols and binding are. An attribute profile on the other hand establishes specific rules for interpretation of attributes in SAML attribute assertions. For instance, X.500/LDAP profile details how to carry X.500/LDAP attributes within SAML attribute assertions.
SAML metadata defines a way to express and share configuration information between SAML entities. For instance, an entity's supported SAML bindings, operational roles (IDP, SP, etc), identifier information, supporting identity attributes, and key information for encryption and signing can be expressed using SAML metadata XML documents. SAML Metadata is defined by its own XML schema. In a number of situations, a service provider may need to have detailed information regarding the type and strength of authentication that a user employed when they authenticated at an identity provider.
SAML authentication context is used in (or referred to from) an assertion's authentication statement to carry this information. A service provider can also include an authentication context in a request to an identity provider to request that the user be authenticated using a specific set of authentication requirements, such as a multi-factor authentication.

SAML Assertion
An assertion is a package of information that supplies zero or more statements made by a SAML authority usually about a subject such as a user. SAML assertions are issued from the Identity Provider(also called Asserting Party) to the Service Provider (also called as Relying Party). When the user has authenticated with the Identity Provider a SAML Assertion is sent to the Service Provider with the Identity Provider's information about that user. It is represented by the <Subject> element. SAML specification defines three different kinds of assertion statements that can be created by a SAML authority. All SAML-defined statements are associated with a subject. The three kinds of statement defined in the specification are:
  • Authentication: The subject was authenticated by a particular means at a particular time.
  • Attribute: The subject is associated with the supplied attributes with values mostly using LDAP.
  • Authorization Decision: A request to allow the subject to access the specified resource has been granted or denied using the given evidence.
SAML authentication request protocol enables third-party authentication of a subject. It is useful in the cases to limit the scope within which an identifier is used to a small set of system entities.

Name Identifiers
Name Identifiers are identifiers for subjects and the issuers of assertions and protocol messages. They help to establish a means by which parties may be associated with identifiers that are meaningful to each of the parties. They help to limit the scope within which an identifier is used to a small set of system entities. Two or more system entities may use the same name identifier value when referring to different identities. SAML provides name qualifiers to disambiguate a name identifier by effectively placing it in a federated namespace related to the name qualifiers. The <BaseID> element is an extension point that allows applications to add new kinds of identifiers. The NameIDType complex type is used when an element serves to represent an entity by a string-valued name. Its more restricted form of identifier than the <BaseID> element and is the type underlying both the <NameID> and <Issuer> elements. The <NameID> element is of type NameIDType, and is used in various SAML assertion constructs such as the <Subject> and <SubjectConfirmation> elements, and in various protocol messages. The <EncryptedID> element is of type EncryptedElementType, and carries the content of an unencrypted identifier element in encrypted fashion. The <Issuer> element, with complex type NameIDType, provides information (name etc) about the issuer of a SAML assertion or protocol message.

Assertions has following elements:
  • The <AssertionIDRef> element makes a reference to a SAML assertion by its unique identifier. The specific authority who issued the assertion or from whom the assertion can be obtained is not specified as part of the reference. 
  • The <AssertionURIRef> element makes a reference to a SAML assertion by URI reference.
  • The <Assertion> element is of the AssertionType complex type and specifies the basic information common to all assertions, such as version issual time, identifier, issuer, signature, subject, authentication etc.
  • The SAML assertion MAY be signed adding the <ds:Signature> element, which provides both authentication of the issuer and integrity protection.
  • The <EncryptedAssertion> element represents an assertion in encrypted fashion.

The Subjects section defines the SAML constructs used to describe the subject of an assertion. The optional <Subject> element specifies the principal that is the subject of all of the (zero or more) statements in the assertion. It identifies the subject using <BaseID>, <NameID>, or <EncryptedID> and confirms it using <SubjectConfirmation> element. A <Subject> element can contain both an identifier and zero or more subject confirmations which a relying party (service provider) can verify when processing an assertion. A <Subject> element SHOULD NOT identify more than one principal.
  • The <SubjectConfirmation> element provides the means for a relying party (service provider) to verify the correspondence of the subject of the assertion with the party with whom the relying party is communicating. It has the method which identifies a protocol or mechanism to be used to confirm the subject.
  • The <SubjectConfirmationData> element has specifies additional data that allows the subject to be confirmed or constrains the circumstances under which the act of subject confirmation can take place. The KeyInfoConfirmationDataType complex type constrains a <SubjectConfirmationData> element to contain one or more <ds:KeyInfo> elements that identify cryptographic keys that are used in some way to authenticate an attesting entity.

The <Conditions> element place constraints on the acceptable use of SAML, such as Validity, Audience Restriction, Usage and Proxy Restrictions.
The <Advice> element contains any additional information that the SAML authority wishes to provide to a relying party (service provider).
The <Statement> element is an extension point that allows other assertion-based applications to reuse the SAML assertion framework.
The <AuthnStatement> element describes a statement by the SAML authority asserting that the assertion subject was authenticated by a particular means at a particular time.
The <SubjectLocality> element specifies the DNS domain name and IP address for the system from which the assertion subject was authenticated.
The <AuthnContext> element specifies the context of an authentication event and can contain authentication context class reference, an authentication context declaration or declaration reference,
or both.
The <AttributeStatement> element describes a statement by the SAML authority asserting that the assertion subject is associated with the specified attributes. Assertions containing <AttributeStatement> elements MUST contain a <Subject> element. It has <Attribute>, <AttributeValue>, <EncryptedAttribute> and <AuthzDecisionStatement> elements.

SAML protocol messages can be generated and exchanged using a variety of protocols. The protocols defined by SAML achieve the following actions:
  • Returning one or more requested assertions. This can occur in response to either a direct request for specific assertions or a query for assertions that meet particular criteria.
  • Performing authentication on request and returning the corresponding assertion.
  • Registering a name identifier or terminating a name registration on request.
  • Retrieving a protocol message that has been requested by means of an artifact.
  • Performing a near-simultaneous logout of a collection of related sessions (“single logout”) on request.
  • Providing a name identifier mapping on request.

RequestAbstractType
All SAML requests are of types that are derived from the abstract RequestAbstractType complex type. It has following attributes:
  • ID: An unique identifier required for the request.
  • Version: The version of this request.
  • IssueInstant: The time instant of issue of the request encoded in UTC.
  • Destination: An optional URI reference indicating the address to which this request has been sent in order to prevent malicious forwarding of requests to unintended recipients.
  • Consent: An optional indicator which indicates that the consent has been obtained from a principal in the sending of this request.
  • Issuer: An optional <saml:Issuer> identifies the entity that generated the request message.
  • Signature: An optional <ds:Signature> that authenticates the requester and provides message integrity.
  • Extensions: The extension point contains optional protocol message extension elements that are agreed on between the communicating parties.

StatusResponseType
All SAML responses are of types that are derived from the StatusResponseType complex type. It has following attributes:
  • ID: An unique identifier required for the response.
  • InResponseTo: A reference to the identifier of the request to which the response corresponds.
  • Version: The version of this response.
  • IssueInstant: The time instant of issue of the response encoded in UTC.
  • Destination: An optional URI reference indicating the address to which this response has been sent in order to prevent malicious forwarding of responses to unintended recipients.
  • Consent: An optional indicator which indicates that the consent has been obtained from a principal in the sending of this response.
  • Issuer: An optional <saml:Issuer> identifies the entity that generated the response message.
  • Signature: An optional <ds:Signature> that authenticates the responder and provides message integrity.
  • Extensions: The extension point contains optional protocol message extension elements that are agreed on between the communicating parties.
  • Status: The <Status> is the required code representing the status of the corresponding request. It contains <StatusCode> representing the status of the activity, <StatusMessage> and <StatusDetail> having additional information concerning the status of the request. The status code can be successful with code as "urn:oasis:names:tc:SAML:2.0:status:Success" or varying failure codes as in the specification.
The existing assertions can be requested by uniquely identified reference using <AssertionIDRequest> or queried for assertions by subject or statement type using the <SubjectQuery>, <AuthnQuery>, <RequestedAuthnContext>, <AttributeQuery> and <AuthzDecisionQuery> elements.

The <Response> message element which is an extension of StatusResponseType is used when a response consists of a list of zero or more assertions that satisfy the request. It has additional <saml:Assertion> or <saml:EncryptedAssertion> which specifies an assertion or encrypted assertion by value. In response to a SAML-defined query message, every assertion returned by a SAML authority must contain a <saml:Subject> element that matches the <saml:Subject> element found in the query. The identifier element (<BaseID>, <NameID>, or <EncryptedID>) or at least one <saml:SubjectConfirmation> element must match between the <saml:Subject> elements of the query and its response.

Authentication Request Protocol
When a principal wants to obtain assertions containing authentication statements to establish a security context at one or more relying parties, it uses the authentication request protocol to send an <AuthnRequest> message element to a SAML authority. The returned <Response> message which contains one or more assertions must have at least one assertion which contains at least one authentication statement. Initially the Requester creates the authentication request. The Presenter then sends the <AuthnRequest> message providing the properties required for resulting assertion to the identity provider and either authenticates itself to the identity provider or relies on an existing security context to establish its identity. The process of authentication of the presenter may take place before, during, or after the initial delivery of the <AuthnRequest> message. The <AuthnRequest> message is mostly signed or authenticated by the protocol binding used to deliver the message. An Identity Provider provides identifiers for users looking to interact with a system, and issues an assertion along with an authentication statement. The request presenter ideally is the attesting entity which satisfies the subject confirmation requirements within the <SubjectConfirmation> elements of the resulting assertion. The responder replies to an <AuthnRequest> with a <Response> message either containing one or more assertions meeting the specifications defined by the request or a <Status> describing the error occurred. The presenter can be directed to another identity provider by the responder while issuing its own <AuthnRequest> message, so that the resulting assertion can be used to authenticate the presenter to the original responder. The returned assertion(s) contains a <saml:Subject> element which represents the presenter. The identifier type and format are determined by the identity provider. At least one statement in at least one assertion is a <saml:AuthnStatement> which describes the authentication performed by the responder or authentication service associated with it. The resulting assertion(s) also contains a <saml:AudienceRestriction> element referencing the requester as an acceptable relying party (service provider). The Relying Party consumes the assertion(s) to establish a security context and to authenticate or authorize the requested subject in order to provide a service.  Identity provider may skip the creation of a new <AuthnRequest> for the authenticating identity provider, when authenticating the same presenter for a second requester.

The AuthnRequest element extends from RequestAbstractType and adds the below additional attributes.
  • <saml:Subject>: The optional subject attribute specifies the requested subject of the resulting assertion. It may include one or more <saml:SubjectConfirmation> elements to indicate how and/or by whom the resulting assertions can be confirmed. When subject attribute is absent the presenter of the message is presumed to be the requested subject. When no <saml:SubjectConfirmation> elements are included, then the presenter is presumed to be the only attesting entity required.
  • <NameIDPolicy>: It specifies the constraints on the name identifier (e.g. name idenfier format for the URI reference) to be used to represent the requested subject. If omitted any type of identifier supported by the identity provider for the requested subject can be used.
  • <saml:Conditions>: Specifies the SAML conditions the requester expects to limit the validity and/or use of the resulting assertion(s).
  • <RequestedAuthnContext>: Specifies the requirements the requester places on the authentication context that applies to the responding provider's authentication of the presenter.
  • <Scoping>: It specifies a set of identity providers trusted by the requester to authenticate the presenter, as well as limitations and context related to proxying of the <AuthnRequest> message to subsequent identity providers by the responder.
  • ForceAuthn: When "true" the identity provider must authenticate the presenter directly rather than rely on a previous security context. Default value is false.
  • IsPassive: When "true" the identity provider and the user agent itself must not visibly take control of the user interface from the requester and interact with the presenter. Default value is false.
  • AssertionConsumerServiceIndex: Indirectly identifies the location to which the <Response> message should be returned to the requester. It applies only to profiles in which the requester is different from the presenter. When omitted the identity provider returns the <Response> message to the default location associated with the requester for the profile of use. It is mutually exclusive with the AssertionConsumerServiceURL and ProtocolBinding attributes.
  • AssertionConsumerServiceURL: Specifies by value the location to which the <Response> message should be returned to the requester. The responder ensures the value specified is associated with the requester usually by signing the enclosing <AuthnRequest> message is another.
  • ProtocolBinding: A URI reference that identifies a SAML protocol binding to be used when returning the <Response> message.
  • AttributeConsumingServiceIndex: Indirectly identifies information associated with the requester describing the SAML attributes the requester desires or requires to be supplied by the identity provider in the <Response> message.
  • ProviderName: Human-readable name of the requester used by the presenter's user agent or the identity provider.

Artifact Resolution Protocol
The Artifact Resolution Protocol provides the mechanism to transport SAML protocol messages in a SAML binding by reference instead of by value. The requests and responses can be obtained by reference using the protocol. A message sender sends a small piece of data called an artifact using the binding instead of binding a message to a transport protocol. Its mainly used when the bindings is unable to carry the message due to size constraints or usage of secure channel without signature. The <ArtifactResolve> message is used to request that a SAML protocol message be returned in an <ArtifactResponse> message by specifying an artifact that represents the SAML protocol message.The <ArtifactResolve> message is either signed or protected by the protocol binding used to deliver the message. ArtifactResolve element extends RequestAbstractType and adds <Artifact> value that the requester received and now wishes to translate into the protocol message it represents. If the responder recognizes the artifact as valid, then it responds with the associated protocol message in an <ArtifactResponse> message element else the response has no embedded message.

Protocol Bindings
Mappings of SAML request-response message exchanges onto standard messaging or communication protocols are called SAML protocol bindings. It is a mapping of SAML messages to a representation that can be transmitted by an HTTP client over the network interface. All bindings must use HTTP with Secure Sockets Layer (SSL) or Transport Layer Security (TLS). SAML also offers mechanisms for parties to authenticate to one another, but in addition SAML may use other authentication mechanisms to provide security for SAML itself especially when the message passes through an intermediary channels.

RelayState
Some bindings define a "RelayState" mechanism for preserving and conveying state information. The RelayState parameter is used to restore the original application URL so that the user can return to the application with a SAML assertion. Exposing the application URL in SAML messages can be a security risk. For service provider-initiated SSO, the service provider saves the URL and places the name of the cookie in the relay state. For identity provider-initiated SSO this option is not available. Instead we have the identity provider place an alias for the application in the relay state and map the alias to the application on the service provider. RelayState is a parameter used by some SAML protocol implementations to identify the specific resource at the resource provider in an Identity Provider initiated single sign on scenario.

SAML SOAP Binding
SOAP is a lightweight protocol which uses XML technologies to define an extensible messaging framework providing a message construct that can be exchanged over a variety of underlying protocols. A SOAP message is fundamentally a one-way transmission between SOAP nodes from a SOAP sender to a SOAP receiver, possibly routed through one or more SOAP intermediaries. SOAP defines an XML message envelope that includes header and message body sections, allowing data and control information to be transmitted. SAML request-response protocol elements are enclosed within the SOAP message body. SAML messages can be transported using SOAP without re-encoding from the standard SAML schema to one based on the optional SOAP encoding system. A single SOAP message does not have more than one SAML request or response element or any additional XML elements in the SOAP body. SAML SOAP request may have arbitrary headers but does not require any headers to process SAML messages. The SAML message are not cached by the HTTP proxies using the Cache-Control and Pragma headers. The SOAP processing error is returned with a <SOAP-ENV:fault> element, while the SAML error is returned with the <samlp:Status> element within the SOAP body.

Example SOAP Request
 POST /SamlService HTTP/1.1
 Host: www.example.com
 Content-Type: text/xml
 Content-Length: nnn
 SOAPAction: http://www.oasis-open.org/committees/security
 
    
       
           ... 
          
            ...
          
       
    
 

Example SOAP Response
 HTTP/1.1 200 OK
 Content-Type: text/xml
 Content-Length: nnnn
 
   
     
       https://www.example.com/SAML
        ... 
       
       
       
       
         
           ...
         
         
           ...
         
       
     
   
 

HTTP Redirect Binding
SAML protocol messages are transmitted within URL parameters using the HTTP Redirect binding. The XML messages on URL are encoded using specialized URL encodings and transmitted using the HTTP GET method. While the complex message content are sent using HTTP POST or Artifact bindings. Binding endpoints indicate the encodings which they support using the metadata. A URL encoding places the message entirely within the URL query string, and reserves the rest of the URL for the endpoint of the message recipient. A SAMLEncoding query string parameter named is used to identify the encoding mechanism used. When the SAMLEncoding parameter is omitted, then the default value is urn:oasis:names:tc:SAML:2.0:bindings:URL-Encoding:DEFLATE, i.e. DEFLATE encoding which is supported by all endpoints.
      Before applying the DEFLATE compression mechanism to the entire XML content of the original SAML protocol message,  any signature on the SAML protocol message, including the <ds:Signature> XML element is removed. The compressed data is later base64-encoded with linefeeds and whitespaces removed. The base-64 encoded data is then URL-encoded, and added to the URL as SAMLRequest or SAMLResponse query string parameter based on whether the message is SAML request or response. RelayState is included with a SAML protocol message transmitted using HTTP redirect binding. The RelayState data is URL-encoded and placed in an additional RelayState query string parameter. The value of relaystate does not exceed 80 bytes in length and its validity is verified using a checksum with a pseudo-random value. The responder sends the RelayState parameter in the SAML protocol response. If the original SAML protocol message was signed with an XML digital signature then the URL-encoded form of the message is signed. An additional query string parameter SigAlg is included identifying the signature algorithm used to sign the URL-encoded SAML protocol message. Signature is constructed by concatenating RelayState if present, along with SigAlg and SAMLRequest (or SAMLResponse) query parameters ordered as SAMLRequest=value&RelayState=value&SigAlg=value. The resulting octet string is fed into the signature algorithm. The signature is then encoded using the base64 encoding with any whitespace removed, and included as a query string parameter named Signature. The supported signature algorithms are DSAwithSHA1 and RSAwithSHA1, with their URI representations supported with the encoding mechanism. The order of the query string parameters on the resulting URL while verifying signatures varies depending upon implementation. The URL encoding is not canonical and there are multiple encodings for a given value, hence the relying party performs the verification step using the original URL-encoded values it received on the query string. Sample SAML URL with signature is https://idp.com?SAMLResponse=xxxx&SigAlg=xxxx&Signature=xxxx
     When the message is signed, the Destination XML attribute in the root SAML element of the message contains the URL to which the sender has instructed the user agent to deliver the message.  The recipient verifies that the value matches with the location at which the message has been received.

Below are the HTTP request response message exchanges using the HTTP redirect binding.
  • When the user agent first makes an arbitrary HTTP request to a system entity, the system entity decides to initiate a SAML protocol exchange inorder to process the request.
  • The system entity acting as a SAML requester responds to the HTTP request from the user agent by returning a SAML request. The SAML request is returned encoded into the HTTP response's Location header with HTTP status 303 or 302. The user agent delivers the SAML request by issuing an HTTP GET request to the SAML responder.
  • The SAML responder may respond to the SAML request by immediately returning a SAML response or might return arbitrary content to facilitate subsequent interaction with the user agent necessary to fulfill the request.
  • The responder returns a SAML response to the user agent in a similar way as SAML requester responds to the HTTP request. The SAML response is then returned to the SAML requester.
  • Upon receiving the SAML response, the SAML requester returns an arbitrary HTTP response to the user agent.

If the signature and assertion are valid, the service provider establishes a session for the user and redirects the browser to the target resource.

HTTP POST Binding
SAML protocol messages can be transmitted within the base64-encoded content of an HTML form control using HTTP POST binding. It is used when the communicating parties do not share a direct path of communication and, SAML requester or responder need to communicate using an HTTP user agent as an intermediary. Also when the responder requires interactions with the user agent to fulfill the request, HTTP POST binding is used. XML Messages with this binding are encoded into an HTML form control and are transmitted using the HTTP POST method. A SAML protocol message is form-encoded by applying the base-64 encoding rules to the XML representation of the message and placing the result in a hidden form control within a form. Based on the message, SAML request or SAML response, the form control is named SAMLRequest or SAMLResponse respectively. RelayState is optional and included as RelayState hidden form control has maximum length of 80 bytes. The action attribute of the form is the recipient's HTTP endpoint to which the SAML message is delivered, with the method attribute being "POST". All the form control values are transformed to be included in an HTML document.
      The intermediary user agent prevents to rely on the transport layer for end-end authentication. Hence SAML enables Form-encoded messages to be signed before applying base64 encoding. When the message is signed, the Destination XML attribute in the root SAML element contains the URL to which the sender instructed the user agent to deliver the message. The recipient verifies that the value matches the location at which the message has been received. The individual "RelayState" and SAML message values can be integrity protected, but not the combination.


Below are the HTTP request response message exchanges using the HTTP POST binding.
  • When the user agent makes an arbitrary HTTP request to a system entity, the system entity initiates a SAML protocol exchange.
  • The system entity acting as a SAML requester responds to an HTTP request from the user agent by returning a SAML request. The user agent delivers the SAML request by issuing an HTTP POST request to the SAML responder.
  • The SAML responder responds to the SAML request by immediately returning a SAML response or returns arbitrary content to facilitate subsequent interaction with the user agent necessary to fulfill the request.
  • The responder finally returns a SAML response to the user agent to be returned to the SAML requester.
  • Upon receiving the SAML response, the SAML requester returns an arbitrary HTTP response to the user agent.

HTTP Artifact Binding
In the HTTP Artifact binding, the SAML request or the SAML response, or both are transmitted by reference using a small stand-in called an artifact. A separate, synchronous binding, such as the SAML SOAP binding, is used to exchange the artifact for the actual protocol message using the artifact resolution protocol defined in the SAML assertions and protocols specification. The artifact binding can be composed with HTTP Redirect binding to transmit request and response messages in a single protocol exchange using two different bindings. Since the artifact binding is resolved using another synchronous binding, a direct communication path must exist between the SAML message sender and recipient in the reverse direction of the artifact's transmission. The URL parameter encoding or the HTML form control are used for artifact message encoding. RelayState with value upto 80 bytes can be included with a SAML artifact transmitted using artifact binding. The general format of an artifact includes a mandatory two-byte artifact type code (TypeCode) and a two-byte index value identifying a specific endpoint of the artifact resolution service of the issuer (EndpointIndex). Each issuer is assigned an identifying URI, also known as the issuer's entity. The artifact type code contains a 20 byte SourceID which is used by the artifact receiver to determine artifact issuer identity and the set of possible resolution endpoints maintained by destination site.

Below are the HTTP request response message exchanges using the HTTP Artifact binding.
  • When the user agent makes an arbitrary HTTP request to a system entity, the system entity decides to initiate a SAML protocol exchange.
  • The system entity acting as a SAML requester responds to an HTTP request from the user agent by returning an artifact representing a SAML request. If URL-encoded, the artifact is returned encoded into the HTTP response's Location header, and the HTTP status is either 303 or 302. If form-encoded, then the artifact is returned in an XHTML document containing the form and content. The user agent delivers the artifact by issuing either an HTTP GET or POST request to the SAML responder.
  • The SAML responder determines the SAML requester by examining the artifact and issues a <samlp:ArtifactResolve> request containing the artifact to the SAML requester using a direct SAML binding, thus temporarily reversing roles.
  • The SAML requester returns a <samlp:ArtifactResponse> containing the original SAML request message it wishes the SAML responder to process.
  • The SAML responder responds to the SAML request by either immediately returning a SAML artifact or returning an arbitrary content to facilitate subsequent interaction with the user agent necessary to fulfill the request. 
  • The responder finally returns a SAML artifact to the user agent to be returned to the SAML requester. The SAML requester determines the SAML responder by examining the artifact, and issues a <samlp:ArtifactResolve> request containing the artifact to the SAML responder using a direct SAML binding.
  • The SAML responder returns a <samlp:ArtifactResponse> containing the SAML response message it wishes the requester to process.
  • Upon receiving the SAML response, the SAML requester returns an arbitrary HTTP response to the user agent.

SAML URI Binding
The SAML URI Binding supports the encapsulation of a <samlp:AssertionIDRequest> message with a single <saml:AssertionIDRef> into the resolution of a URI. URI resolution can occur over multiple underlying transports mostly HTTP with SSL 3.0. A SAML URI reference identifies a specific SAML assertion. The result of resolving the URI is a message containing the assertion, or a transport-specific error. The specific format of the message depends on the underlying transport protocol. If the transport protocol permits the returned content to be described, then the assertion may be encoded in a custom format. When the same URI reference is resolved in the future, then either the same SAML assertion, or an error, is returned. The SAML reference should consistently reference the same SAML assertion.

Sunday, September 8, 2013

CXF WS Security

  1. Setup the WS Security in Weblogic
  2. Test it using SOAP UI Client
  3. Create CXF Client to Send Request with BST
  4. Receive the Response from CXF Client with Security Confirmation

Setting up WS Security in Weblogic


Oracle Weblogic Server 12c was used to configure with the client application. The client application is the EJB application with an EJB Stateless bean. It uses weblogic.jws.Policies and weblogic.jws.Policy classes to specify the location to the policy file.

@Stateless
@WebService(targetNamespace="http://ws-connector.sp.ttp.tsm.com", name="TTPSPService",
  portName="TTPSPPort", endpointInterface="com.tsm.ttp.sp.ws_connector.TTPSP")
@Policies( { @Policy(uri = "policy:TTPSP-Policy.xml") } )
public class TTPSP  implements com.tsm.ttp.sp.ws_connector.TTPSP {

    public TTPSP() {     }

   @Override
   public CheckEligibilityResponseType checkEligibility(CheckEligibilityRequestType input) {
 CheckEligibilityResponseType result= new CheckEligibilityResponseType();
 return result;
   }
   ...........
}

The policy file located in the “Project/ejbModule/META-INF/policies” folder. The policy.xml specified that it requires “WssX509V3Token11” to the Recipient which is believed to be the Binary Security Token. The algorithm-suite preferred was “Basic256”. Timestamp must be included and, both the Headers and Body be signed entirely. Also specified the requirement of security confirmation using “<sp:RequireSignatureConfirmation/>” element.

To generate the build first we need to generate the “wlfullclient.jar” for the current weblogic server. The JarBuilder is used to create wlfullclient.jar using the following command.
WL_HOME/server/lib> java -jar wljarbuilder.jar

In some cases the "weblogic.jws.Policies" or other packages maybe absent in the wlfullclient.jar recently created. In case of Weblogic 10.3.3, the packages weblogic.jws.Policies and weblogic.jws.Policy are not present in the “wseeclient.jar” and “wls-api.jar” jar files either. These packages (weblogic.jws.Policies) can be found in the jar file
“C:\oracle\Middleware\modules\*ws.api_1.0.0.0.jar*” for Weblogic 10.3.3 and in
“C:\Oracle\Middleware\modules\ws.api_2.0.0.0.jar” for Weblogic 12.1

In Eclipse, we create a “New EJB Project” and all the source packages are added in the “ejbModule” folder. Also the “ejbModule” contains the “META-INF” folder containing the “MANIFEST.MF” and the “policy.xml” files. Create a “lib” folder in the project and add the “wlfullclient-11.1.jar”, “ws.api_1.1.0.0.jar” and other jars required.

Now create a “New Enterprise Application Project” i.e. EAR Project naming it same as previous project with EAR appended at the end. During the creation configure the EAR settings to add J2EE module dependencies. The EAR Project can be created by right clicking the “Deployment Descriptor: Projectname” -> New -> Project -> EAR Project.

In order to configure the weblogic server with WS Security, we need to generate a keystore using java keytool as follows:

1)  Generate a new JKS Keystore with new Keypair:


keytool -genkeypair -alias bank: BANK -keyalg RSA -keysize 1024
        -validity 365 -keystore bank.jks
KeyStore Password: t1bank
                Enter key password for <bank: BANK>: t1bank

2)  Export a certificate from the generate keystore:


keytool -exportcert -alias bank: BANK -file bank.cer -keystore bank.jks
Enter keystore password:
Certificate stored in file <bank.cer>

Now to configure the keystore in weblogic we have two choices, one is to add the keys from the bank.jks keystore to the DemoTrust.jks keystore. The other option is to change the Keystore configuration to use the Custom keystore.
   Initially, we tried to setup a custom keystore using the description from this link. The process was as follows:


  1. In Weblogic server administration, expand Servers and select the server you need to update.
  2. Select Configuration -> Keystores -> SSL.
  3. Click the Change link under Keystore Configuration.
  4. Select Custom Identity and Java Standard Trust as the keystore configuration type and continue.
  5. For the Custom Identity Keystore File Name, enter the path to your Java keystore. Select Keystore type as jks .
  6. Enter your Custom Identity Keystore Passphrase as the password you used when you created the Java keystore
  7. Confirm the password, click Continue and then Finish. 
  8. Go back under Servers and select the server that you are working with.
  9. Select Configuration -> Keystores -> SSL.
  10. Under Configure SSL, select Keystores as the method for storing identities.
  11. Enter the server certificate key alias (in this example, myalias was used), and the keystore password
  12. Click Finish to finalize the changes. You will need to reboot Weblogic for those changes to take effect.
After going with the above approach by changing the "Keystore Configuration" to "Custom Identity and Java Standard Trust" and setting all the JKS Keystores pointing to bank.jks, weblogic console gave the following error:
"weblogic.management.DeploymentException: Deployment could not be created. Deployment creator is null."

The reason for the above error turns to be that the SSL configuration is not been updated corresponding to the Keystore configuration. Hence the “SSL Configuration" was configured to use a “Custom Trust Store” and the Key Alias and Password to be used were specified. It resulted in a failure, as no request was able to hit the Weblogic server.

After learning from the above failures, we swap to the first option, i.e. add the certificate to the DemoTrust.jks. The Demo keystores are the Keystores configured in Weblogic Console by Default. The Demo keystores are configured under (Environment-> Servers-> AdminServer-> Configuration-> Keystores). The names of the Demo keystores and their default passwords are as follows:

Keystore: DemoTrust.jks
Password: DemoTrustKeyStorePassPhrase
Path:     C:\Oracle\Middleware\wlserver_10.3\server\lib

Keystore: DemoIdentity.jks
Password: DemoIdentityKeyStorePassPhrase
Path:     C:\Oracle\Middleware\wlserver_10.3\server\lib

Keystore: cacerts
Password: changeit
Path:     C:\Oracle\Middleware\jdk160_21\jre\lib\security

 All the Demo keystores for the Weblogic server are located in the path “Oracle\Middleware\wlserver_10.3\server\lib”. One could find the "DemoTrust.jks" and "DemoIdentity.jks" files here. Here we add the bank.cer ONLY TO “DemoTrust.jks” keystore and NOT TO “DemoIdentity.jks”. We DON'T ADD bank.cer to "cacerts" in located in “Oracle\Middleware\jdk160_21\jre\lib\security” folder too. The process is as follows:

1)     Add the bank.cer ONLY TO DemoTrust.jks keystore using the following command:
      keytool -importcert -alias bank: BANK -file bank.cer -keystore DemoTrust.jks
      Enter keystore password: DemoTrustKeyStorePassPhrase

        Trust this certificate? [no]: yes
        Certificate was added to keystore

2)    We confirm if the keys are added into the DemoTrust.jks by the following command:
        keytool -list -keystore DemoTrust.jks 

All the server logs can be found in the following log file:
“Oracle\Middleware\user_projects\domains\base_domain\servers\AdminServer\logs\base_domain.log”.

WS Security with BST Client using SOAP-UI


Open the SOAP-UI and create a new project based on the WSDL or Endpoint provided.  In order to set WS Security for the SOAP-UI client, right click on the project created and select “Show Project View” from the Menu.


Select the “WS-Security Configurations” tab and select the “Keystores/Certificates” tab in the inner window.  Then click on the “+” button to select the new Keystore and enter the Keystore password.




Then Select the “Outgoing WS-Security Configurations” tab in the inner window.  Click the add button from the top section to add a new Configuration in the outgoing WS-Security configurations.  Fill in the Default Username/Alias and password to be used in all the WSS Actions.  Now in the bottom section click the “+” button to add a Timestamp Entry. Fill the “Time to Live” as 1800000 and check the option to set the Millisecond Precision of the Timestamp.
      Moving forward, add the second WSS Entry “Signature” which will be creating the Binary Security Token. Select the Keystore which is been entered in the “Keystores/Certificates” section and enter the Alias name with the corresponding password. Select the Key Identifier Type as “Binary Security Token” in order to create the Binary Security Token  first. Select the signature algorithm, canonicalization algorithm and the digest algorithm.  At last check “Use single certificate for signing” in order to use only the base certificate and not all the certificates in the chain. The “Parts” section is kept empty, but by default SOAP-UI will sign the “Body” element using the generated BinarySecurityToken.





Moving forward, add another Signature WSS entry, the third one of all. Similar to the previous Signature configuration, select the keystore, enter alias and password, and select the same entries for the algorithms as before. Most importantly for the Key Identifier Type select “Issuer Name and Serial Number” in order to sign all the elements. The “Use single certificate for signing” option remains unchecked as all the certificates in the chain should be used for signing.  Unlike before, use the “+” button near the “Parts” section to add the “Timestamp”, “Body” and “BinarySecurityToken” elements with the namespace and encoding information (Default its “Content”).


Now the project is WS Security enabled for the Requests. But before firing the individual requests, select the Request Method and under project properties make sure that “Strip whitespaces” Property is set to “true”.


Then click the “Authentication and Security-related settings” for the Request at the bottom causing a window being opened. Select the Outgoing WSS as the same name given in the “Outgoing Security Configurations” section before.



This can also be done by right clicking the request and using the menu to select the “Outgoing WSS” to the corresponding Outgoing WS Security configuration. Mostly the prior method is preferred.


The Resulting SOAP-UI Request is as follows:

   
     
       
         
         
         
         
           
             
           
           
           0up9O5yZ6wLnau/eTzPZtfz+IIM=
         
         
           
             
           
           
           EAuvZTemCXTia8fPYXngIZOCPE0=
         
         
           
             
           
           
           kYMlR5YhU9CHpVaL0uCVnxINNF0=
         
         
         FSSax.....CWtoxx0=
         
        
         
           
              CN=BANK,OU=BANK,O=BANK,L=SG,ST=SG,C=SG 
              1329894156
           
       
     
     
   
   
           l4TLCUURhrJbRjXEIEGirTpg==
   
   
     
       
       
       
         
           
      
         
         EAuvZTemCXTia8fPYXngIZOCPE0=
       
     
     TmjGBLZJ69kHZNG8=
     
        
          
        
    


    2012-02-22T08:07:59.352Z
    2012-03-14T04:07:59.352Z
 
 
 
 
      
            1222
            232
            CheckEligibility
      
 


From the above request format received from SOAP-UI for the WS Security enabled Server, we could point out some of the key things. First, the Security Header inside the Soap Header contains the following elements:
  1. Signature 1
  2. BinarySecurityToken
  3. Signature 2
  4. Timestamp
(highlighted in Blue above) while Signature 2 consists of <ds:KeyInfo> Element.
       In Signature 1 we find the <ds:X509Data> Element (highlighted in Blue) inside the <wsse:SecurityTokenReference> element. The <ds:X509Data> Element contains the <ds:X509IssuerSerial> element.  From its name it suggests that this is signed by the IssuerSerial KeyIdentifier. Also in Singature 1 element we find three <ds:Reference> elements assumed to be signatures (from the order of Signature Parts specified in SOAP-UI) as follows:
  1. TIMESTAMP                       : <ds:Reference URI="#Timestamp-8">
  2. BODY                                   : <ds:Reference URI="#id-10">
  3. BINARYSECURITYTOKEN:  <ds:Reference URI="#CertId-2B6B2C4066C46E9954132989807937513">
    In Signature 2 on the other hand we see just the <wsse:Reference> element inside the <wsse:SecurityTokenReference> element. The  <wsse:Reference> element has the ValueType as “X509v3” which suggests that this is signed by the BinarySecurityToken. Even though we didn’t specify any values for “Parts” section in the first Signature using BinarySecurityToken as KeyIdentifier, we see one <ds:Reference URI="#id-10"> element assumed to be a signature.  Comparing the URI of the Reference element with Signature 1 element signatures, we assume that it is the Signature of the Body Element. Hence even if the Signature Parts is empty, by default the Body element is signed by Default using the specified KeyIdentifier.


Create CXF Client to Send Request with BST


    One of a Senior developer Xei Songwen provided an implementation of WS Security using which just signed Body element to send the request. The classes contained a Dispatcher, Client, Customized WSS4JOutInterceptor implementation, PasswordCallback, SigningCheck.properties and the Spring configuration described in the Class Diagram.


The following Jar Issues were faced and resolved while testing the application initially:

ERROR:
Caused by: java.lang.NoClassDefFoundError: org.apache.axiom.soap.impl.dom.soap11.SOAP11Factory
       at org.apache.axis2.saaj.SOAPPartImpl.<init>(SOAPPartImpl.java:209)
       at org.apache.axis2.saaj.SOAPPartImpl.<init>(SOAPPartImpl.java:246)

ADDED:  saaj-impl-1.3.2.jar
REMOVED: axis2-saaj-1.4.jar

ERROR:
Caused by: java.lang.NoClassDefFoundError: com.sun.org.apache.xerces.internal.dom.DocumentImpl
       at java.lang.ClassLoader.defineClassImpl(Native Method)
       at java.lang.ClassLoader.defineClass(ClassLoader.java:223)

ADDED:  xercesImpl-sun-version.jar

ERROR:
Caused by: java.lang.IncompatibleClassChangeError
       at org.apache.xalan.transformer.TransformerIdentityImpl.createResultContentHandler(TransformerIdentityImpl.java:207)
       at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:330)
       at com.sun.xml.messaging.saaj.util.transform.EfficientStreamingTransformer.transform(EfficientStreamingTransformer.java:423)
       at com.sun.xml.messaging.saaj.soap.EnvelopeFactory.createEnvelope(EnvelopeFactory.java:136)
       at com.sun.xml.messaging.saaj.soap.ver1_1.SOAPPart1_1Impl.createEnvelopeFromSource(SOAPPart1_1Impl.java:102)
       at com.sun.xml.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:156)
       at com.sun.xml.messaging.saaj.soap.MessageImpl.getSOAPBody(MessageImpl.java:1287)
       at

ADDED:  saaj-api-1.3.2.jar

The spring configuration for the WSS4JOutInterceptor is as follows:

       
               
               
               
                 
                 
                 
                 
                 
                             
                                     passwordCallbackRef
                            
                           
                
                
                  <!—“DirectReference” -->
                
                
                
                

               
               
       


When tried to use the KeyIdentifier as “DirectReference” or “IssuerSerial” in the Single WSS4JOutInterceptor and specified BinarySecurityToken element in the “signatureparts” as specified above, it gave the following error:

Caused by: org.apache.ws.security.WSSecurityException: General security error (WSEncryptBody/WSSignEnvelope: Element to encrypt/sign not found: http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd, BinarySecurityToken)
at org.apache.ws.security.message.WSSecSignature.addReferencesToSign(WSSecSignature.java:588)
 at org.apache.ws.security.message.WSSecSignature.build(WSSecSignature.java:769)
 at org.apache.ws.security.action.SignatureAction.execute(SignatureAction.java:57)

In order to tackle the problem of missing BinarySecurityToken element in the SecurityHeader before the Interceptor tries to sign the BST (BinarySecurityToken) element,  BST element is added before the request is passed to the inoke() method. The code added is as follows:

final String XMLNS_WSU = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
final String XSD_WSSE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";

final SOAPFactory sf = SOAPFactory.newInstance();
final SOAPElement securityElement = sf.createElement("Security", "wsse", XSD_WSSE);
final SOAPElement authElement = sf.createElement("BinarySecurityToken", "wsse", XSD_WSSE);
authElement.setAttribute("EncodingType", " http://.....1.0#Base64Binary");
authElement.setAttribute("ValueType", "http://.....1.0#X509v3");
authElement.setAttribute("wsu:Id", "CertId-CA440EE13ADE87BAE5133044746778913");
authElement.addAttribute(new QName("xmlns:wsu"), XMLNS_WSU);
authElement.addTextNode("SMDFhdffIUSDFJL9090ddf213asdsKFHkfdfgjfs234gbhfg56icxdd24rgd"));
securityElement.addChildElement(authElement);
soapRequest.getSOAPHeader().addChildElement(securityHeader);


But instead of detecting the BST element and trying to sign it, the WSS4JOutInterceptor throws the following exception:

org.apache.xmlbeans.XmlException: error: Attribute "Id" bound to namespace "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" was already specified for element "wsse:BinarySecurityToken".

Considering the suggestion given from the CXF Forum two interceptors extending WSS4JOutInterceptor were configured. The first one is configured with the KeyIdentifier as “DirectReference”, while the second one configured as “IssuerSerial”. Now the BinartSecurityToken (BST) was generated but nothing was signed. Also the Issuer Serial along with Timestamp elements was absent in the SecurityHeader. On reversing the KeyIdentifier values across the two interceptors, BinarySecurityToken vanished but all the previously missing elements reappeared.  This lead to a suspicion that only the first interceptor was being called while the second interceptor remained unexecuted.
      After running the debugger numerous times, the doubt was confirmed. As mentioned by somebody in the forum that the instance names of the two interceptors along with their class names should be different in order for them to be executed. But still success remained far off. One doubt still pondered that both the interceptors extend the WSS4JOutInterceptor for all their functionality with just the Class name different.
    After looking at the source code of org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor below, it seems to be a possibility that getId() method of the WSS4JOutInterceptorInternal Class is called before calling the handleMessage() method of the inner class. This handleMessage() method (line 257) in turn calls the doSenderAction() method defined in the org.apache.ws.security.handler.WSHandler Class.


public class  WSS4JOutInterceptor extends AbstractWSS4JInterceptor {
       ...................................

   private WSS4JOutInterceptorInternal ending;

   public  WSS4JOutInterceptor() {
         super();
         setPhase(Phase.PRE_PROTOCOL);
         getAfter().add(SAAJOutInterceptor.class.getName());
         ending = createEndingInterceptor();
   }

       ...................................
   final class  WSS4JOutInterceptorInternal implements PhaseInterceptor {
            ...................................
     public void  handleMessage(SoapMessage mc) throws Fault { …………. 
           doSenderAction(doAction, doc, reqData, actions, somebooleanvalue);
     }
            ...................................
     public String  getId() {

            return WSS4JOutInterceptorInternal.class.getName();
     }
            ...................................
   }
}


If the getId() method of the WSS4JOutInterceptorInternal Class is altered to return a different class name rather than the actual one, then following exception is thrown:

SystemErr     R javax.xml.ws.soap.SOAPFaultException: Unknown exception, internal system processing error.
SystemErr     R      at org.apache.cxf.jaxws.DispatchImpl.mapException(DispatchImpl.java:235)
SystemErr     R      at org.apache.cxf.jaxws.DispatchImpl.invoke(DispatchImpl.java:264)
SystemErr     R      at org.apache.cxf.jaxws.DispatchImpl.invoke(DispatchImpl.java:195)

When a new Interceptor (MSMBSTWSS4JOutInterceptor) imitating the same code copied from WSS4JOutInterceptor is added along with the old Interceptor (MSMWSS4JOutInterceptor) extending WSS4JOutInterceptor, then both the Interceptors are invoked one after the another. Hence the first Interceptor creates the BinarySecurityToken while the second Interceptor (extending WSS4JOutInterceptor) signs all the elements including the BinarySecurityToken created before.

The same issue of signing the BinarySecurityToken can be resolved by overriding the Apache CXF and SAAJ classes. We first override the doSenderAction() method of the WSHandler Class in the BSTWSS4JOutInterceptor implementation.

public class BSTWSS4JOutInterceptor extends WSS4JOutInterceptor {

 private static final String msmActionClass = “org.example.BSTSignatureAction”; 

 protected void doSenderAction(int doAction, Document doc, RequestData reqData,
                               Vector actions, boolean isRequest){

     boolean mu = decodeMustUnderstand(reqData);
     ............
     ............
     for (int i = 0; i < actions.size(); i++) {
       int actionToDo = ((Integer) actions.get(i)).intValue();
       ............
       switch (actionToDo) {
       case WSConstants.UT:
       case WSConstants.ENCR:
       case WSConstants.SIGN:
       case WSConstants.ST_SIGNED:
       case WSConstants.ST_UNSIGNED:
       case WSConstants.TS:
       case WSConstants.UT_SIGN:

    if (isBSTEnabled && actionToDo == WSConstants.SIGN) {
  
           Action doit = null;
           
           try {
            doit = (Action) Loader.loadClass(msmActionClass).newInstance();
           } catch (Throwable t) {
               if (log.isDebugEnabled()) {
                 log.debug(t.getMessage(), t);
               }
               throw new WSSecurityException(WSSecurityException.FAILURE,
               "unableToLoadClass", new Object[] { msmActionClass }, t);
           }

    if(doit != null) {
  doit.execute(this, actionToDo, doc, reqData);
    }

  } else {
  wssConfig.getAction(actionToDo).execute(this, actionToDo, doc, reqData);
   }

         break;

       case WSConstants.NO_SERIALIZE:
                reqData.setNoSerialization(true);
                break;
       default:
                Action doit = null;     
     ............
     ............
 }
}


Now in the overridden BSTSignatureAction class we override the implementation of the execute() method inorder to change the WSSecSignature class to BSTWSSecSignature class as follows:

public class BSTSignatureAction implements Action {

 public void execute(WSHandler handler, int actionToDo, Document doc,
                     RequestData reqData){

     String password = handler.getPassword(...).getPassword();
     BSTWSSecSignature wsSign = new BSTWSSecSignature();
     ............
     ............
     ............
     try {
      wsSign.build(doc, reqData.getSigCrypto(), reqData.getSecHeader());
      reqData.getSignatureValues().add(wsSign.getSignatureValue());
     }
     catch() { ... }
 }
}


At last we override the Now in the overridden BSTSignatureAction class we override the implementation of the execute() method inorder to change the WSSecSignature class to BSTWSSecSignature class as follows:
public class BSTWSSecSignature extends WSSecBase {

............
 public Document build(Document doc, Crypto cr, WSSecHeader secHeader)
                 throws WSSecurityException{

     ............ 
     // call addBST() method, a duplicate of prepare() method were keyIdentifierType is 
     // considered only as BST_DIRECT_REFERENCE in its switch case.
     addBST(doc, cr, secHeader);
        
     // create an empty vector for signature parts 
     Vector bstparts = new Vector();
        
     if(parts != null) {
        for (WSEncryptionPart part : (Vector)parts)
        {
          if(part.getName().equalsIgnoreCase("Body")) {
           // add the BODY element as by default if signature parts is empty
           // it signs the BODY element.
            bstparts.add(part);
          }
        }
     }
        
     // add the empty signature to the Security Header
     addReferencesToSign(bstparts, secHeader);
     // prepend the signature at the top of the Security Header
     prependToHeader(secHeader);
     // compute the digest values for the BODY element signature using the 
     // BinarySecurityToken 
     computeSignature();
        
     if (bstToken != null) {
        // prepend the BinarySecurityToken element at the top of the signature in 
        // Security Header
        prependBSTElementToHeader(secHeader);
     }
        
     // continue with the normal process of signing and adding IssuerSerial signatures
     prepare(doc, cr, secHeader);
     SOAPConstants soapConstants = 
     WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());

     if (parts == null) {
        parts = new Vector();
        WSEncryptionPart encP = 
            new WSEncryptionPart(
                soapConstants.getBodyQName().getLocalPart(), 
                soapConstants.getEnvelopeURI(), 
                "Content"
            );
        parts.add(encP);
     }

     addReferencesToSign(parts, secHeader);
     prependToHeader(secHeader);
     // Eliminate call to prependBSTElementToHeader() as it is called beforehand
     computeSignature();

     return doc;
}
     ............ 
}


Receiving Response with Security Confirmation:


Initially “enableSignatureConfirmation” was set to “true” only in the wss4jInConfiguration.

 
               ......................
               
                       
                               
                                ......................
                               
                       
               
               ......................
 


This caused the following error to pop up:

0000001e SystemErr     R Caused by: org.apache.ws.security.WSSecurityException:
 WSHandler:  Check Signature confirmation: got SC element, but no matching SV
       at org.apache.ws.security.handler.WSHandler.checkSignatureConfirmation(WSHandler.java:392)
       at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:224)

After repeated combinations and retries it became clear that “enableSignatureConfirmation” has to be set “true” not only for the Wss4jInInterceptor but for both WSS4JOutInterceptors.  The reason predicted is that, there are two “SecurityConfirmation” elements added in the Response from the Weblogic Server. Now at the receiver end, when we enable the “enableSignatureConfirmation” entry in Wss4jInInterceptor, it tries to check for the Security Vector if there are similar two entries in order to verify the corresponding incoming two elements. As both the WSS4JOutInterceptors didn’t  enable the “enableSignatureConfirmation” entry, there are no entries in the Security Vector to verify. Hence we get the above exception.

......................
<wsse11:SecurityConfirmation>sdfsa9er8sd9f8sd9fgds</wsse11:SecurityConfirmation>
<wsse11:SecurityConfirmation>sdfsa9er8sd9f8sd9fgds</wsse11:SecurityConfirmation>
......................

                           
               ....................
               
                       
                               
                                ....................
                               
                       
               
               ....................
       


Further when tried to alter the contents of even one of the element, the same error as below is thrown again as the contents of the SC elements don’t match with the contents in the SC Vectors.

org.apache.cxf.binding.soap.SoapFault: WSHandler: Check Signature confirmation: got a SC element, but no stored SV.

Going further when the value of the “action” entry was “Timestamp Signature” it threw the following exception:

Security processing failed (actions mismatch)
Caused by: org.apache.ws.security.WSSecurityException: An error was discovered processing the <wsse:Security> header
at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:290)


After debugging the source it was found that the exception originated from line number 290 of the class org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor. Following was the piece of the code:

// now check the security actions: do they match, in any order?

  if (!ignoreActions && !checkReceiverResultsAnyOrder(wsResult, actions)) {
      LOG.warning("Security processing failed (actions mismatch)");
      throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
  }

The call to the checkReceiverResultsAnyOrder() method returned false causing it to throw the WSSecurityException. After deeper look in the source code of the checkReceiverResultsAnyOrder() method in org.apache.ws.security.handler.WSHandler class it was found that it compares the Elements in the response with the Actions specified in the configuration entry of WSS4JInInterceptor. It checks whether the same actions are specified corresponding to the elements present in the <SecurityHeader>  of the response. But from the line highlighted in red below, <SecurityConfirmation> and <BinarySecurityToken> elements in the response doesn’t need to have the corresponding Action name in the configuration. This seems logical as the possible values for the “action” entry in the configuration are { NoSecurity , UsernameToken , UsernameTokenNoPassword , SAMLTokenUnsigned , SAMLTokenSigned , Signature , Encrypt , Timestamp , UsernameTokenSignature }.

protected boolean checkReceiverResultsAnyOrder(Vector wsResult, Vector actions);

  java.util.List recordedActions = new Vector(actions.size());

        for (int i = 0; i < actions.size(); i++) {
 
           Integer action = (Integer)actions.get(i); 
           recordedActions.add(action);
        }
 
        for (int i = 0; i < wsResult.size(); i++) {
 
          final Integer actInt = (Integer) ((WSSecurityEngineResult) wsResult
                     .get(i)).get(WSSecurityEngineResult.TAG_ACTION);

          int act = actInt.intValue();

          if (act == WSConstants.SC || act == WSConstants.BST) {
             continue;
          }
 
          if (!recordedActions.remove(actInt)) {
             return false;
          }
        }
 
         if (!recordedActions.isEmpty()) {
             return false;
         }
         return true;
     }


Now looking at the response below from the WS Security enabled Weblogic server, the possible values for the action should be corresponded with , , . But using the above information, there is no such action as “enableSignatureConfirmation” and hence we are left with only the “Timestamp” action in the WS Security configuration entry resolving the exception.

   
      
         
         
         
           2012-03-02T19:35:55Z
           2012-03-02T19:36:55Z 
         
      
   
   
      
         100
         SUCCESS
      
   



When a request is sent to the Oracle Weblogic Server at last the following error was encountered:
WSDLException (at /con:soapui-project): faultCode=INVALID_WSDL: Expected element '{http://schemas.xmlsoap.org/wsdl/}definitions' when trying to load.

On carefully looking the request sent by the Client with the one sent by SOAP-UI, it was found that the Request tag for Client Request was "<CheckEligibility>" while the Request Type of SOAP-UI was "<CheckEligibility Request>".