Archive

Archive for the ‘WebLogic’ Category

SAML2.0 Weblogic Sender-Vouches Configuration & POC

June 4, 2016 8 comments

This blog post intends to highlight on the SAML2.0 configuration for web services in Weblogic. It details step-by-step guide to configure weblogic domains with a sample test client to test the web service. We will look into SAML2.0 Sender Vouches web service configuration.

What is Sender Vouches?

Sender-Vouches – The asserting party (different from the subject) vouches for the verification of the subject. The receiver must have a trust relationship with the asserting party.

Sender Vouches
1. Rather than authenticating with the STS, here, Client authenticates with an intermediate service.
2. The intermediary gets the security token from the STS.
3. Then it signs the request and sends to the RP.
4. RP trusts both the intermediary and the STS. So, it validates both of them.

Here are the steps:

  • Configure STS (Weblogic Domain – Certificate used is wssipsts
  • Configure Weblogic domain for weblogic web service with SAML2.0 Sender Vouches policy – Bob is used for this
  • Create a stand alone client that which retrieves token from STS and fires a request to web service with SAML1.1 token retrieved from STS – Alice is used for this

Configure STS:

  1. Create a weblogic domain here ‘am using weblogic 10.3.5
  2. We need to configure SSL for this domain
  3. While creating the domain I configure weblogic to use 6001 for Non-SSL and 6002 for SSL port. Let domain name be STSDomain.
  4. Now go to http://localhost:6001/console
  5. Got to STSDomain –> Environment –> Admin Server –> Keystores
    • Select Custom Identity and Custom Trust
    • Custom Identity Keystore: F:\Oracle\Middleware\user_projects\domains\STSDomain\certs\oasis.jks
    • Type: JKS
    • password: password
    • Custom Trust Keystore: F:\Oracle\Middleware\user_projects\domains\STSDomain\certs\cacerts
    • Type: JKS
    • password: changeit
    • Save and restart server if it asks to do so
  6. Got to STSDomain –> Environment –> Admin Server –>SSL
    • Private Key Alias: WssIPSTS
    • Private Key passphrase: password
    • Save and restart if asked to do so
  7. Now build the web service StsUnt.java and deploy it in the domain. Check after successful deployment whether you can open the WSDL url or not.
  8. STSDomain–>Security Realms –>myrealm
  9. We need to configure only ‘Credential Mapper’ here. Credential Mapper basically responsible for Issuing SAML tokens. Where as identity Asserter are responsible for validating the SAML tokens. So we will configure Credential Mapper for STS and Identity Asserter for webservice
  10. Go to Providers –> Credential Mapping
  11. Add PKI Credential Mapper
    • In Provider Specific tab, Keystore Provider: SUN
    • Keystore Type: JKS
    • Keystore file name: F:\Oracle\Middleware\user_projects\domains\STSDomain\certs\oasis.jks
    • Keystore pass phrase: password
    • Use resource hierarchy and Initator group names check boxes should be selected.
    • Click on save and restart if asked to do so
  12. Add SAML2CredentialMapper
    • In Configuration –> Provider specific tab, Issuer URI: www.oracle.com
    • Name Qualifier: www.oracle.com
    • Default time to live: 120
    • offset: 0
    • Webservice Assertion Signing key alias: WssIPSTS
    • Key pass phrase: password
    • Select check box ‘Generate Attributes’
    • Save and go to Management tab in the same section
    • New–>New Webservice Service Provider Partner
    • Add sender vouches relying party: Sendervouches:/echoservicesaml2/EchoServiceSAML2
    • Make sure to select ‘Enabled’ check box
    • Give description
    • Audience URIs:  target:*:http://HYD-69ZRV01-L:7001/echoservicesaml2
    • Generate Attributes checkbox to be selected
    • Select confirmation methods as ‘Sender-Vouches’
    • Save and restart the server if asked to do so
  13. That’s all the configuration from STS side.

Configure Weblogic Webservice:

  1. Create a weblogic domain here ‘am using weblogic 10.3.5
  2. We do not need to configure SSL for this domain
  3. While creating domain configure weblogic to use 7001 port and no SSL port required. Let the domain name be ‘WebserviceDomain’
  4. Login to weblogic console.
  5. WebserviceDomain–>servers–>Adminserver–>keystore
    • Custom Identity and Custom Trust store
    • Custom Identity Keystore: F:\Oracle\Middleware\user_projects\domains\WebserviceDomain\certs\oasis.jks
    • Key type: JKS
    • password: password
    • Trust Keystore: F:\Oracle\Middleware\user_projects\domains\WebserviceDomain\certs\cacerts
    • Type: JKS
    • password: changeit
    • Save and restart the server if asked to do so.
    • SSL
    • Private key alias: Bob
    • password: password
    • Save
  6. Build and deploy the weblogic web service. The scripts and the webservice code is given below.
  7. Go to security realm–>myrealm–>Providers–>Authentication
    • Add SAMLAuthenticator
    • Make control Flag as ‘SUFFICIENT’
    • Make control Flag of Default Authenticator too as ‘SUFFICIENT’
    • (optional step) Also in Default Authenticator’s ‘Provider Specific’ Enable password digest, minimum password length as 1 and save.
    • (optional step) In Default Identity Asserter’s –> Common. chose Active Types ‘wsse:passworddigest’ and ‘x.509’ send it to right and click on save.
    • (optional step) In Defaul Identity Asserter –> Provider Specific. Default Username as @, Mapper attribute type as ‘CN’, select ‘use default user name mapper’ and click on Save button. Restart if asked to do so
  8. Got to security realm–>myrealm–>Providers–> Authentication
    • Add SAML2IdentityAsserterV
    • Go to Management –> New –> New Webservice Identity Provider Partner
    • Name: Sendervouches:/echoservicesaml2/EchoServiceSAML2
    • Chose Enabled
    • Audience URIs: target:*:/echoservicesaml2
    • Issuer URI: www.oracle.com
    • Virtual User selected
    • Confirmation Method: Sender-Vouches
    • Process Attributes selected
    • Save and restart if asked to do so.
  9. That’s all the configuration of web service.

Client Testing:

  1. Open a command prompt window
  2. Run setWLSEnv.cmd from that command window to set the paths
  3. ant runsaml2
  4. That’s all for now…

StsUnt.java

package com.saml.example;</pre>
<pre>import weblogic.jws.Policy;
 import weblogic.wsee.security.saml.SAMLTrustTokenProvider;
 import weblogic.wsee.security.wst.framework.TrustTokenProviderRegistry;</pre>
<pre>import javax.jws.WebMethod;
 import javax.jws.WebService;</pre>
<pre>@WebService
 @Policy(uri="policy:Wssp1.2-2007-Wssc1.3-Bootstrap-Https-UNT.xml")
 public class StsUnt {
         static {
         init();
     }
     @WebMethod
     @Policy(uri="policy:Wssp1.2-2007-SignBody.xml")
     public String dummyMethod(String s) {
         return s;
     }
    static void init() {
         TrustTokenProviderRegistry reg = TrustTokenProviderRegistry.getInstance();
         SAMLTrustTokenProvider provider = <span class="il">new</span> MySAMLTrustTokenProvider();
         reg.registerProvider("<a href="http://docs.oasis-open.org/wss/2004/01/oasis-2004-01-saml-token-profile-1.0#SAMLAssertionID" target="_blank">http://docs.oasis-open.org/wss/2004/01/oasis-2004-01-saml-token-profile-1.0#SAMLAssertionID</a>", provider);
         reg.registerProvider("<a href="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID" target="_blank">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID</a>", provider);
         reg.registerProvider("<a href="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" target="_blank">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</a>",  provider);
         reg.registerProvider("<a href="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.0" target="_blank">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.0</a>",  provider);
         reg.registerProvider("<a href="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" target="_blank">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1</a>",  provider);
     }
    static class MySAMLTrustTokenProvider extends SAMLTrustTokenProvider {</pre>
<pre>    }
 }

build.xml for StsUnt.java

<?xml version="1.0"?>
<project name="SenderVouches11" default="all" basedir=".">
<property name="root.dir" value="${basedir}" />
<taskdef name="jwsc" classname="weblogic.wsee.tools.anttasks.JwscTask" />
<taskdef name="clientgen" classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
<taskdef name="wldeploy" classname="weblogic.ant.taskdefs.management.WLDeploy" />
<taskdef name="wsdlc" classname="weblogic.wsee.tools.anttasks.WsdlcTask" />
<property file="${basedir}/properties.txt" />
<property name="source.dir" value="${basedir}" />
<property name="output.dir" value="${basedir}/build" />
<path id="class.path">
<pathelement path="${java.class.path}" />
</path>
<target name="all" depends="clean,jwsc,deploy" />
<target name="build" depends="clean,jwsc" />
<target name="clean">
<delete dir="${output.dir}" />
</target>
<target name="jwsc">
<antcall target="jwsc-sts" />
</target>
<target name="jwsc-sts">
<jwsc srcdir="${source.dir}" destdir="${output.dir}" debug="on" classpath="${class.path}">
<module contextpath="standalonests" name="standalonests" explode="true">
<jws file="StsUnt.java" type="JAXWS">
<WLHttpTransport serviceUri="SamlSTS" />
</jws>
</module>
</jwsc>
</target>
<target name="deploy">
<antcall target="deploy-sts" />
</target>
<target name="deploy-sts">
<wldeploy action="deploy" source="${output.dir}/standalonests" user="${sts-wls-username}" password="${sts-wls-passwd}" verbose="false" adminurl="t3://${sts-wls-server}" debug="false" targets="${sts-wls-target}" />
</target>
<target name="undeploy">
<property name="wls-admin-server" value="${wls-server}" />
<wldeploy action="undeploy" name="standalonests" user="${sts-wls-username}" password="${sts-wls-passwd}" verbose="false" adminurl="t3://${sts-wls-server}" debug="false" targets="${sts-wls-target}" />
</target>
<property name="extra-server-verbose" value="
-Dweblogic.xml.crypto.encrypt.verbose=true
-Dweblogic.xml.crypto.dsig.debug=true
-Dweblogic.xml.crypto.dsig.verbose=true
-Dweblogic.wsee.security.debug=true
-Dweblogic.wsee.security.verbose=true
-Dweblogic.xml.crypto.wss.debug=true
-Dweblogic.xml.crypto.wss.verbose=true
-Dweblogic.xml.crypto.keyinfo.debug=true
-Dweblogic.xml.crypto.keyinfo.verbose=true
-Dweblogic.xml.crypto.dsig.debug=true
-Dweblogic.xml.crypto.dsig.verbose=true
-Dweblogic.xml.crypto.encrypt.debug=true
-Dweblogic.xml.crypto.encrypt.verbose=true
-Dweblogic.debug.DebugSecuritySAMLService=true
-Dweblogic.debug.DebugSecuritySAMLCredMap=true
-Dweblogic.debug.DebugSecuritySAMLAtn=true
-Dweblogic.debug.DebugSecuritySAMLLib=true
-Dweblogic.debug.DebugSecuritySAML2Service=true
-Dweblogic.debug.DebugSecuritySAML2CredMap=true
-Dweblogic.debug.DebugSecuritySAML2Atn=true
-Dweblogic.debug.DebugSecuritySAML2Lib=true
-Dweblogic.debug.DebugSecurityCredMap=true
-Dweblogic.log.StdoutSeverity=Debug" />
</project>

properties.txt for StsUnt.java

certs.dir=${root.dir}/../certs/
 config.dir=${root.dir}/../config/
 build.dir=${root.dir}/../build
 sts.stage.dir=${build.dir}/sts_stage</pre>
<pre>sts-wls-host=localhost
 sts-wls-port=6001
 sts-wls-server=${sts-wls-host}:${sts-wls-port}
 sts-wls-username=weblogic
 sts-wls-passwd=Welcome1
 sts-wls-target=AdminServer</pre>
<pre># common properties
 sts-sport=6002</pre>
<pre>sts-server-keystore-name=${root.dir}/../certs/oasis.jks</pre>
<pre>sts-server-keystore-pass=password
 sts-serverKey=${sts.stage.dir}/WssIPPrv.pem
 sts-server-cert=${sts.stage.dir}/WssIPCert.pem
 sts-server-alias=WssIPSTS
 sts-server-cert-alias=WssIPSTS
 sts-server-certs-pass=password
 sts-server-key-pass=password
 sts-server-truststore-name=${sts.stage.dir}/cacerts
 sts-server-truststore-pwd=changeit</pre>
<pre>samlStsURL=https://${sts-wls-host}:${sts-sport}/standalonests/SamlSTS</pre>
<pre> 

EchoServiceSAML2.java

package com.saml.example;</pre>
<pre>import weblogic.jws.Policies;
 import weblogic.jws.Policy;
 import javax.jws.WebService;</pre>
<pre>@Policies(
   {
     @Policy(uri = "policy:Wssp1.2-2007-Saml2.0-SenderVouches-Wss1.1-Asymmetric.xml"),
     @Policy(uri = "policy:Wssp1.2-2007-SignBody.xml"),
     @Policy(uri = "policy:Wssp1.2-2007-EncryptBody.xml")
   }
 )</pre>
<pre>@WebService
 public class EchoServiceSAML2 {
   public String echo( String hello){
   System.out.println("Inside EchoServiceSAML2!!!");
     return hello;
   }
 }

build.xml for webservice

</pre>
<pre>
<?xml version="1.0"?> <project name="SenderVouches11" default="all" basedir=".">     <property name="root.dir" value="${basedir}" />     <taskdef name="jwsc" classname="weblogic.wsee.tools.anttasks.JwscTask" />     <taskdef name="clientgen" classname="weblogic.wsee.tools.anttasks.ClientGenTask" />     <taskdef name="wldeploy" classname="weblogic.ant.taskdefs.management.WLDeploy" />     <taskdef name="wsdlc" classname="weblogic.wsee.tools.anttasks.WsdlcTask" /></pre>
<pre>    <property file="${basedir}/properties.txt" /></pre>
<pre>    <property name="source.dir" value="${basedir}" />
     <property name="output.dir" value="${basedir}/build" />
     <property name="clientclasses.dir" value="${basedir}/build/client" />
     <property name="clientclassessaml2.dir" value="${basedir}/build/clientsaml2" />
     
     <path id="class.path">
         <pathelement path="${java.class.path}" />
         <pathelement path="${basedir}/build/client" />
         <pathelement path="${basedir}/build/clientsaml2" />
     </path></pre>
<pre>    <target name="all" depends="clean,jwsc,deploy,client" /></pre>
<pre>    <target name="build" depends="clean,jwsc,client" /></pre>
<pre>    <target name="clean">
         <delete dir="${output.dir}" />
     </target></pre>
<pre>    <target name="jwsc">
         <antcall target="jwsc-ws" />
     </target></pre>
<pre>    <target name="jwsc-ws">
         <jwsc srcdir="${source.dir}" destdir="${output.dir}" debug="on" classpath="${class.path}">
             <module contextpath="echoservice" name="echoservice" explode="true">
                 <jws file="EchoService.java" type="JAXWS">
                     <WLHttpTransport serviceUri="EchoService" />
                 </jws>
             </module>
         </jwsc>
        
         <jwsc srcdir="${source.dir}" destdir="${output.dir}" debug="on" classpath="${class.path}">
             <module contextpath="echoservicesaml2" name="echoservicesaml2" explode="true">
                 <jws file="EchoServiceSAML2.java" type="JAXWS">
                     <WLHttpTransport serviceUri="EchoServiceSAML2" />
                 </jws>
             </module>
         </jwsc>
     </target>
     
     <target name="clientgen">
         <mkdir dir="${clientclasses.dir}" />
         <clientgen destdir="${clientclasses.dir}" wsdl="${basedir}/EchoService.wsdl" type="JAXWS" packageName="com.saml.example" />
         <clientgen destdir="${clientclassessaml2.dir}" wsdl="${basedir}/EchoServiceSAML2.wsdl" type="JAXWS" packageName="com.saml.example" />
     </target>
     
     <target name="client">
         <mkdir dir="${clientclasses.dir}" />
         <copy todir="${clientclasses.dir}" overwrite="true">
             <fileset dir="${certs.dir}" includes="*" />
         </copy>
         <antcall target="clientgen" />
         <javac debug="true" srcdir="${source.dir}" destdir="${clientclasses.dir}">
             <classpath refid="class.path" />
             <include name="EchoServicePortClient.java" />
         </javac>
         <javac debug="true" srcdir="${source.dir}" destdir="${clientclassessaml2.dir}">
             <classpath refid="class.path" />
             <include name="EchoServiceSAML2PortClient.java" />
         </javac>
     </target>
</pre>
<pre>    <target name="deploy">
         <antcall target="deploy-ws" />
     </target></pre>
<pre>    <target name="deploy-ws">
         <wldeploy action="deploy" source="${output.dir}/echoservice" user="${wls-username}" password="${wls-passwd}" verbose="false" adminurl="t3://${wls-server}" debug="false" targets="${wls-target}" />
         <wldeploy action="deploy" source="${output.dir}/echoservicesaml2" user="${wls-username}" password="${wls-passwd}" verbose="false" adminurl="t3://${wls-server}" debug="false" targets="${wls-target}" />
     </target></pre>
<pre>    <target name="undeploy">
         <property name="wls-admin-server" value="${wls-server}" />
         <wldeploy action="undeploy" name="echoservice" user="${wls-username}" password="${wls-passwd}" verbose="false" adminurl="t3://${wls-server}" debug="false" targets="${wls-target}" />
         <wldeploy action="undeploy" name="echoservicesaml2" user="${wls-username}" password="${wls-passwd}" verbose="false" adminurl="t3://${wls-server}" debug="false" targets="${wls-target}" />
     </target>
     
     <target name="run">
         <java classname="com.saml.example.client.EchoServicePortClient" fork="true">
             <classpath refid="class.path" />
             <jvmarg line="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8453
               ${extra-server-verbose}
               -Dweblogic.wsee.verbose=*,!weblogic.wsee.connection.soap.SoapConnectionMessage" /></pre>
<pre>        </java>
     </target>
     
     <target name="runsaml2">
         <java classname="com.saml.example.client.EchoServiceSAML2PortClient" fork="true">
             <classpath refid="class.path" />
             <jvmarg line="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8453
               ${extra-server-verbose}
               -Dweblogic.wsee.verbose=*,!weblogic.wsee.connection.soap.SoapConnectionMessage" /></pre>
<pre>        </java>
     </target>
     
     <property name="extra-server-verbose" value="
       -Dweblogic.xml.crypto.encrypt.verbose=true
       -Dweblogic.xml.crypto.dsig.debug=true
       -Dweblogic.xml.crypto.dsig.verbose=true
       -Dweblogic.wsee.security.debug=true
       -Dweblogic.wsee.security.verbose=true
       -Dweblogic.xml.crypto.wss.debug=true
       -Dweblogic.xml.crypto.wss.verbose=true
       -Dweblogic.xml.crypto.keyinfo.debug=true
       -Dweblogic.xml.crypto.keyinfo.verbose=true
       -Dweblogic.xml.crypto.dsig.debug=true
       -Dweblogic.xml.crypto.dsig.verbose=true
       -Dweblogic.xml.crypto.encrypt.debug=true
       -Dweblogic.xml.crypto.encrypt.verbose=true
       -Dweblogic.debug.DebugSecuritySAMLService=true
       -Dweblogic.debug.DebugSecuritySAMLCredMap=true
       -Dweblogic.debug.DebugSecuritySAMLAtn=true
       -Dweblogic.debug.DebugSecuritySAMLLib=true
       -Dweblogic.debug.DebugSecuritySAML2Service=true
       -Dweblogic.debug.DebugSecuritySAML2CredMap=true
       -Dweblogic.debug.DebugSecuritySAML2Atn=true
       -Dweblogic.debug.DebugSecuritySAML2Lib=true
       -Dweblogic.debug.DebugSecurityCredMap=true
       -Dweblogic.log.StdoutSeverity=Debug" />
 </project>

properties.txt for webservice

certs.dir=${root.dir}/../certs/ config.dir=${root.dir}/../config/ build.dir=${root.dir}/../build</pre>
<pre>wls-host=localhost
 wls-port=7001
 wls-server=${wls-host}:${wls-port}
 wls-username=weblogic
 wls-passwd=Welcome1
 wls-target=AdminServer

EchoServicePortClient.java

package com.saml.example.client;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceRef;
import weblogic.security.SSL.TrustManager;
import weblogic.wsee.message.WlMessageContext;
import weblogic.wsee.security.bst.ClientBSTCredentialProvider;
import weblogic.wsee.security.saml.SAMLTrustCredentialProvider;
import weblogic.wsee.security.unt.ClientUNTCredentialProvider;
import weblogic.xml.crypto.wss.provider.CredentialProvider;
import com.saml.example.*;
import weblogic.wsee.security.saml.*;
import weblogic.wsee.jaxrpc.WLStub;
import weblogic.jws.Policies;
import weblogic.jws.Policy;
import weblogic.xml.crypto.wss.WSSecurityContext;
import weblogic.security.principal.WLSPrincipal;
import weblogic.wsee.jaxrpc.WLStub;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import java.util.*;
import java.security.Principal;
import javax.security.auth.Subject;
public class EchoServiceSAML2PortClient {
     @WebServiceRef
     private static EchoServiceSAML2Service echoServiceService;
    private static String stsUntPolicy = "&lt;?xml version=\"1.0\"?&gt;\n"
             + "&lt;wsp:Policy\n"
             + "  xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\"\n"
             + "  xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\"\n"
             + "  &gt;\n"
             + "  &lt;sp:TransportBinding&gt;\n"
             + "    &lt;wsp:Policy&gt;\n"
             + "      &lt;sp:TransportToken&gt;\n"
             + "        &lt;wsp:Policy&gt;\n"
             + "          &lt;sp:HttpsToken/&gt;\n"
             + "        &lt;/wsp:Policy&gt;\n"
             + "      &lt;/sp:TransportToken&gt;\n"
             + "      &lt;sp:AlgorithmSuite&gt;\n"
             + "        &lt;wsp:Policy&gt;\n"
             + "          &lt;sp:Basic256/&gt;\n"
             + "        &lt;/wsp:Policy&gt;\n"
             + "      &lt;/sp:AlgorithmSuite&gt;\n"
             + "      &lt;sp:Layout&gt;\n"
             + "        &lt;wsp:Policy&gt;\n"
             + "          &lt;sp:Lax/&gt;\n"
             + "        &lt;/wsp:Policy&gt;\n"
             + "      &lt;/sp:Layout&gt;\n"
             + "      &lt;sp:IncludeTimestamp/&gt;\n"
             + "    &lt;/wsp:Policy&gt;\n"
             + "  &lt;/sp:TransportBinding&gt;\n"
             + "  &lt;sp:SupportingTokens&gt;\n"
             + "    &lt;wsp:Policy&gt;\n"
             + "      &lt;sp:UsernameToken\n"
             + "        sp:IncludeToken=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient\"&gt;\n"
             + "        &lt;wsp:Policy&gt;\n" + "          &lt;sp:WssUsernameToken10/&gt;\n"
             + "        &lt;/wsp:Policy&gt;\n" + "      &lt;/sp:UsernameToken&gt;\n"
             + "    &lt;/wsp:Policy&gt;\n" + "  &lt;/sp:SupportingTokens&gt;\n"
             + "&lt;/wsp:Policy&gt;";
    public static void main(String[] args) {
         System.setProperty(
                 "com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump",
                 "true");
         try {
            String wsURL = "http://HYD-69ZRV01-L:7001/echoservicesaml2/EchoServiceSAML2?WSDL";
            echoServiceService = new EchoServiceSAML2Service(new URL(wsURL),
                     new QName("http://example.saml.com/",
                             "EchoServiceSAML2Service"));
             EchoServiceSAML2 echoService = echoServiceService.getEchoServiceSAML2Port();
            System
                     .setProperty("javax.net.ssl.trustStore",
                             "F:/Oracle/Middleware/user_projects/domains/WebserviceDomain/certs/cacerts");
            Map&lt;String, Object&gt; requestContext = ((BindingProvider) echoService)
                     .getRequestContext();
            List&lt;CredentialProvider&gt; credList = new ArrayList&lt;CredentialProvider&gt;();
            // Add the necessary credential providers to the list
             InputStream policy = new ByteArrayInputStream(stsUntPolicy
                     .getBytes("UTF-8"));
             requestContext.put(WlMessageContext.WST_BOOT_STRAP_POLICY, policy);
            String stsURL = "https://HYD-69ZRV01-L:6002/standalonests/SamlSTS";
            requestContext.put(WlMessageContext.STS_ENDPOINT_ADDRESS_PROPERTY,
                     stsURL);
             requestContext.put(WSSecurityContext.TRUST_MANAGER,
                     new TrustManager() {
                         public boolean certificateCallback(
                                 X509Certificate[] chain, int validateErr) {
                             // need to validate if the server cert can be
                             // trusted
                             return true;
                         }
                     });
            requestContext.put(WLStub.SAML_ATTRIBUTE_ONLY, "False");
             credList.add(new SAMLTrustCredentialProvider());
             credList.add(new MySAMLCredentialProvider1());
            String username = "Alice";
             String password = "Interop1";
             credList.add(new ClientUNTCredentialProvider(username.getBytes(),
                     password.getBytes()));
            // ClientBSTCredentialProvider
             String defaultClientcert = "F:/Oracle/Middleware/user_projects/domains/WebserviceDomain/certs/Alice.cer";
             String clientcert = System.getProperty("target.clientcert",
                     defaultClientcert);
             String defaultClientkey = "F:/Oracle/Middleware/user_projects/domains/WebserviceDomain/certs/Alice.prv";
             String clientkey = System.getProperty("target.clientkey",
                     defaultClientkey);
            String defaultServerCert = "F:/Oracle/Middleware/user_projects/domains/WebserviceDomain/certs/Bob.cer";
             String serverCert = System.getProperty("target.serverCert",
                     defaultServerCert);
            credList.add(new ClientBSTCredentialProvider(clientcert, clientkey,
                     serverCert));
            requestContext.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST,
                     credList);
            // Add your code to call the desired methods.
             System.out.println(echoService.echo("Hello SAML2"));
        } catch (Exception ex) {
             ex.printStackTrace();
         }
     }
     /**
    * This Credntail Provider is for SMAL 2.0 Sender Vouches
    */
  private static class MySAMLCredentialProvider1 extends SAML2CredentialProvider {
    public SAMLAttributeStatementData getSAMLAttributeData(Subject subject) {
      System.out.println(" Prividing SAML Attributes from MySAMLCredentialProvider1 for Subject =" + subject);
       // There are four types of attributes in this test
      SAMLAttributeStatementData attributes = new SAMLAttributeStatementDataImpl();
      String xmlns = "www.oracle.com/webservices/saml/test";
      // 1. The attribute without value
       SAMLAttributeData attribute1 = new SAMLAttributeDataImpl();
       attribute1.setAttributeName("test.no.value.attribute");
       // Friendly name is optional. It is set in this example.
       attribute1.setAttributeFriendlyName("Type 1 - No Value");
       attribute1.setAttributeNameSpace(xmlns);
       attributes.addAttributeInfo(attribute1);
      // 2. Static attribute that has static value
       SAMLAttributeData attribute2 = new SAMLAttributeDataImpl();
       attribute2.setAttributeName("test.static.attribute");
       attribute2.setAttributeFriendlyName("Type 2 - Static Attribute");
       attribute2.setAttributeNameSpace(xmlns);
       attribute2.addAttributeValue("static.attribute.value");
       attributes.addAttributeInfo(attribute2);
      // 3. Subjust dependent attributes
       SAMLAttributeData attribute3 = new SAMLAttributeDataImpl();
       attribute3.setAttributeName("test.subject.dependent.attribute");
       attribute3.setAttributeFriendlyName("Type 3 - Subject Dependent Attribute");
       attribute3.setAttributeNameSpace(xmlns);
       if (hasUser("Alice", subject)) {
         attribute3.addAttributeValue("Alice A");
       } else if (hasUser("Bob", subject)) {
         attribute3.addAttributeValue("Bob B");
       } else {
         attribute3.addAttributeValue("Hacker X");
       }
       attributes.addAttributeInfo(attribute3);
      // 4. Multiple value attributes
       SAMLAttributeData attribute4 = new SAMLAttributeDataImpl();
       attribute4.setAttributeName("test.multi.value.attribute");
       attribute4.setAttributeFriendlyName("Type 4 - Multi-Value Attribute");
       attribute4.setAttributeNameSpace(xmlns);
       if (hasUser("Alice", subject)) {
         attribute4.addAttributeValue("Team Lead");
         attribute4.addAttributeValue("Programmer");
       } else if (hasUser("Bob", subject)) {
         attribute4.addAttributeValue("System Admin");
         attribute4.addAttributeValue("QA");
       } else {
         attribute4.addAttributeValue("Hacker");
         attribute4.addAttributeValue("meber of unkown");
       }
       attributes.addAttributeInfo(attribute4);
       return attributes;
     }
    private static boolean hasUser(String user, Subject subject) {
       if (null == user || null == subject) {
         return false;
       }
       Set principals = subject.getPrincipals();
       if (null == principals || principals.isEmpty()) {
         return false;
       }
       for (Iterator it = principals.iterator(); it.hasNext();) {
         Object obj = it.next();
         if (obj instanceof Principal) {
           Principal p = (Principal) obj;
           if (user.equals(p.getName())) {
             return true;
           }
         } else if (obj instanceof WLSPrincipal) {
           WLSPrincipal principal = (WLSPrincipal) obj;
           if (user.equals(principal.getName())) {
             return true;
           }
         }
       }
       return false;
     }
   }
 }

SAML2 Assertion is not yet valid (NotBefore condition)


My current setup:

Oracle STS is running on Machine 1 and Oracle Weblogic Web service is running on Machine 2

When I wrote a client to invoke SAML2 token from STS on Machine 1 and use the token to call SAML2 web service on weblogic running on Machine 2. My client constantly kept throwing following error:

<16 Jun, 2014 5:48:56 PM IST> <Debug> <SecuritySAML2Atn> <BEA-000000> <found idp partner with targetResource: /echoservicesaml2/EchoServiceSAML2>
<16 Jun, 2014 5:48:56 PM IST> <Debug> <SecuritySAML2Atn> <BEA-000000> <SAML2Assert: Start verify assertion signature>
<16 Jun, 2014 5:48:56 PM IST> <Debug> <SecuritySAML2Atn> <BEA-000000> <SAML2Assert: The assertion is signed.>
<16 Jun, 2014 5:48:56 PM IST> <Debug> <SecuritySAML2Atn> <BEA-000000> <SAML2Assert: End verify assertion signature>
<16 Jun, 2014 5:48:56 PM IST> <Debug> <SecuritySAML2Atn> <BEA-000000> <SAML2Assert: Start verify assertion attributes>
<16 Jun, 2014 5:48:56 PM IST> <Debug> <SecuritySAML2Atn> <BEA-000000> <SAML2Assert: End verify assertion attributes>
<16 Jun, 2014 5:48:56 PM IST> <Debug> <SecuritySAML2Atn> <BEA-000000> <SAML2Assert: Start verify assertion issuer>
<16 Jun, 2014 5:48:56 PM IST> <Debug> <SecuritySAML2Atn> <BEA-000000> <SAML2Assert: End verify assertion issuer>
<16 Jun, 2014 5:48:56 PM IST> <Debug> <SecuritySAML2Atn> <BEA-000000> <SAML2Assert: Start verify assertion conditions>
<WSEE:12>Exception while asserting identity: javax.security.auth.login.LoginException: [Security:090377]Identity Assertion Failed, weblogic.security.spi.IdentityAssertionException: [Security:090377]Identity Assertion Failed, weblogic.security.spi.IdentityAssertionException: [Security:096537]Assertion is not yet valid (NotBefore condition).<CSSUtils.assertIdentity:429>

Root Cause:
Oracle STS returned token appropriately, but the request fails on the weblogic server.

After a bit of fight we could figure out that the Machine 2 time is 2 minutes behind Machine 1. When we adjusted the times (synced) of Machine 1 and Machine 2 things worked smoothly there after.

Hope this tip helps some one there.

Configuration settings are unavailable because /Farm_IDMDomain/asinst_1/oid2 is down


Problem:

If you see an error in the Enterprise Manager console as shown below, follow the solution that might solve the issue.

Information: Configuration settings are unavailable because /Farm_<domain>/<asinst>/oid1 is down.

Solution:

  • Restart with opmnctl stopall and opmnctl startall
  • Restart weblogic admin
  • Start weblogic managed server wls_ods1
  • Start weblogic managed server wls_oif1
  • opmnctl stopproc ias-component=EMAGENT
  • opmnctl startproc ias-component=EMAGENT
  • Now try in /em console this time you should see the details

Weblogic SOAP request response – Debug Flag List


Following are some of the weblogic debug flags useful to view soap envelope request and response in the weblogic server logs:
-Dweblogic.wsee.verbose=*

For SAML (1.1 and 2):

-Dweblogic.debug.DebugSecuritySAMLService=true
-Dweblogic.debug.DebugSecuritySAMLCredMap=true
-Dweblogic.debug.DebugSecuritySAMLAtn=true
-Dweblogic.debug.DebugSecuritySAMLLib=true
-Dweblogic.debug.DebugSecuritySAML2Service=true
-Dweblogic.debug.DebugSecuritySAML2CredMap=true
-Dweblogic.debug.DebugSecuritySAML2Atn=true
-Dweblogic.debug.DebugSecuritySAML2Lib=true
-Dweblogic.debug.DebugSecurityCredMap=true
-Dweblogic.log.StdoutSeverity=Debug
For WebService Security:
-Dweblogic.xml.crypto.wss.debug=true
-Dweblogic.xml.crypto.wss.verbose=true
-Dweblogic.xml.crypto.keyinfo.debug=true
-Dweblogic.xml.crypto.keyinfo.verbose=true
-Dweblogic.xml.crypto.dsig.debug=true
-Dweblogic.xml.crypto.dsig.verbose=true
-Dweblogic.xml.crypto.encrypt.debug=true
-Dweblogic.xml.crypto.encrypt.verbose=true
You may add these debug statement <weblogic_domain>\bin\setDomainEnv.cmd as JAVA_PROPERTIES and restart the weblogic domain.
Doing so you should now be able to see SOAP envelope request & response.
Reference:

Adding java.util.List to JMS Queue – Sample Code

December 24, 2012 1 comment

I was looking at a way to add java.util.ArrayList collection to existing JMS Queue & here is how you do it.

You may replace ArrayList with Map/HashMap as well.

This post uses my previous post’s JMS Queue Configuration.

Sender Code Snippet

import java.io.Serializable;
import java.util.List;

import javax.jms.JMSException;
import javax.jms.ObjectMessage;

/**
 * This adds java.util.List to JMS Queue
 *
 * @author karun.chennuri
 *
 */
public class JMSQueueSender {

 private ObjectMessage msg;
 /**
 * Sends a message to a JMS queue.
 *
 * @param message message to be sent
 * @exception JMSException if JMS fails to send message due to internal error
 */
 public void send(List<String> listData) throws Exception {
 JMSContextSender context = JMSContextSender.getInstance(); //Get JMS Context. Replace with appropriate code to get JMSContext
 msg = context.getQueueSession().createObjectMessage(); //Get Queue Session and create Object Message

 msg.setObject((Serializable)listData);
 context.getQueueSender().send(msg);
 System.out.println("message sent...");
 }

}

Receiver Code Snippet

import java.util.ArrayList;
import java.util.List;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.QueueConnection;
import javax.jms.QueueReceiver;

/**
 *
 * Receiver Code. Receives ArrayList from Queue
 * @author karun.chennuri
 *
 */
public class JMSQueueReceiver implements MessageListener {

/**

* Message listener interface.
 *
 * @param msg
 * message
 */
 public void onMessage(Message msg) {
 try {
 List<String> listData = null;
 ObjectMessage objMessage = (ObjectMessage) msg;

listData = (ArrayList) objMessage.getObject();

System.out.println("listData: " + listData);

} catch (JMSException jmse) {
 System.err.println("An exception occurred: " + jmse.getMessage());
 }
 }

}

Java JMS Client

December 24, 2012 Leave a comment

Well this code has been taken from sample code from Oracle JMS Sender/Receiver.

Had you followed my previous post on JMS configuration then below the source code should work fine, else you might want to modify connection factory, queue, weblogic server credentials and weblogic server port. Rest all should work fine. Good Luck!

Here is the Source code for JMS Sender. Run this program…
package sample.queue;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/** This example shows how to establish a connection
 * and send messages to the JMS queue. The classes in this
 * package operate on the same JMS queue. Run the classes together to
 * witness messages being sent and received, and to browse the queue
 * for messages. The class is used to send messages to the queue.
 *
 * @author Copyright (c) 1999,2010, Oracle and/or its affiliates. All Rights Reserved.

* @modified Karun Chennuri
 */
public class QueueSend
{
 // Defines the JNDI context factory.
 public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";

// Defines the JMS context factory.
 public final static String JMS_FACTORY="jms/AlertConnectFactory"; //This should match your configuration

// Defines the queue.
 public final static String QUEUE="jms/AlertQueue"; //This should match your configuration

private QueueConnectionFactory qconFactory;
 private QueueConnection qcon;
 private QueueSession qsession;
 private QueueSender qsender;
 private Queue queue;
 private TextMessage msg;

/**
 * Creates all the necessary objects for sending
 * messages to a JMS queue.
 *
 * @param ctx JNDI initial context
 * @param queueName name of queue
 * @exception NamingException if operation cannot be performed
 * @exception JMSException if JMS fails to initialize due to internal error
 */
 public void init(Context ctx, String queueName)
 throws NamingException, JMSException
 {
 qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
 qcon = qconFactory.createQueueConnection();
 qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
 queue = (Queue) ctx.lookup(QUEUE);
 qsender = qsession.createSender(queue);
 msg = qsession.createTextMessage();
 qcon.start();
 }

/**
 * Sends a message to a JMS queue.
 *
 * @param message message to be sent
 * @exception JMSException if JMS fails to send message due to internal error
 */
 public void send(String message) throws JMSException {
 msg.setText(message);
 qsender.send(msg);
 }

/**
 * Closes JMS objects.
 * @exception JMSException if JMS fails to close objects due to internal error
 */
 public void close() throws JMSException {
 qsender.close();
 qsession.close();
 qcon.close();
 }
 /** main() method.
 *
 * @param args WebLogic Server URL
 * @exception Exception if operation fails
 */
 public static void main(String[] args) throws Exception {
 InitialContext ic = getInitialContext("t3://localhost:7001");
 QueueSend qs = new QueueSend();
 qs.init(ic, QUEUE);
 readAndSend(qs);
 qs.close();
 }

private static void readAndSend(QueueSend qs)
 throws IOException, JMSException
 {
 BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));
 String line=null;
 boolean quitNow = false;
 do {
 System.out.print("Enter message (\"quit\" to quit): \n");
 line = msgStream.readLine();
 if (line != null && line.trim().length() != 0) {
 qs.send(line);
 System.out.println("JMS Message Sent: "+line+"\n");
 quitNow = line.equalsIgnoreCase("quit");
 }
 } while (! quitNow);

}

private static InitialContext getInitialContext(String url)
 throws NamingException
 {
 Hashtable<String,String> env = new Hashtable<String,String>();
 env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
 env.put(Context.PROVIDER_URL, url);
 env.put(Context.SECURITY_PRINCIPAL, "weblogic");
 env.put(Context.SECURITY_CREDENTIALS, "<mypassword>"); //replace with your password

return new InitialContext(env);
 }

}

Here is the source code for Receiver. Run this program…

package sample.queue;

import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * This example shows how to establish a connection to
 * and receive messages from a JMS queue. The classes in this
 * package operate on the same JMS queue. Run the classes together to
 * witness messages being sent and received, and to browse the queue
 * for messages. This class is used to receive and remove messages
 * from the queue.
 *
 * @author Copyright (c) 1999,2010, Oracle and/or its affiliates. All Rights Reserved.
 * @modified Karun Chennuri
 */
public class QueueReceive implements MessageListener
{
 // Defines the JNDI context factory.
 public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";

// Defines the JMS connection factory for the queue.
 public final static String JMS_FACTORY="jms/AlertConnectFactory";

// Defines the queue.
 public final static String QUEUE="jms/AlertQueue";

private QueueConnectionFactory qconFactory;
 private QueueConnection qcon;
 private QueueSession qsession;
 private QueueReceiver qreceiver;
 private Queue queue;
 private boolean quit = false;

/**
 * Message listener interface.
 * @param msg message
 */
 public void onMessage(Message msg)
 {
 try {
 String msgText;
 if (msg instanceof TextMessage) {
 msgText = ((TextMessage)msg).getText();
 } else {
 msgText = msg.toString();
 }

System.out.println("Message Received: "+ msgText );

if (msgText.equalsIgnoreCase("quit")) {
 synchronized(this) {
 quit = true;
 this.notifyAll(); // Notify main thread to quit
 }
 }
 } catch (JMSException jmse) {
 System.err.println("An exception occurred: "+jmse.getMessage());
 }
 }

/**
 * Creates all the necessary objects for receiving
 * messages from a JMS queue.
 *
 * @param ctx JNDI initial context
 * @param queueName name of queue
 * @exception NamingException if operation cannot be performed
 * @exception JMSException if JMS fails to initialize due to internal error
 */
 public void init(Context ctx, String queueName)
 throws NamingException, JMSException
 {
 qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
 qcon = qconFactory.createQueueConnection();
 qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
 queue = (Queue) ctx.lookup(queueName);
 qreceiver = qsession.createReceiver(queue);
 qreceiver.setMessageListener(this);
 qcon.start();
 }

/**
 * Closes JMS objects.
 * @exception JMSException if JMS fails to close objects due to internal error
 */
 public void close()throws JMSException
 {
 qreceiver.close();
 qsession.close();
 qcon.close();
 }
/**
 * main() method.
 *
 * @param args WebLogic Server URL
 * @exception Exception if execution fails
 */

public static void main(String[] args) throws Exception {
 InitialContext ic = getInitialContext("t3://localhost:7001");
 QueueReceive qr = new QueueReceive();
 qr.init(ic, QUEUE);

System.out.println("JMS Ready To Receive Messages (To quit, send a \"quit\" message).");

// Wait until a "quit" message has been received.
 synchronized(qr) {
 while (! qr.quit) {
 try {
 qr.wait();
 } catch (InterruptedException ie) {}
 }
 }
 qr.close();
 }

private static InitialContext getInitialContext(String url)
 throws NamingException
 {
 Hashtable<String,String> env = new Hashtable<String,String>();
 env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
 env.put(Context.PROVIDER_URL, url);
 env.put(Context.SECURITY_PRINCIPAL, "weblogic");
 env.put(Context.SECURITY_CREDENTIALS, "<mypassword>");
 return new InitialContext(env);
 }

}

Oracle WebLogic JMS Queue Configuration

December 24, 2012 Leave a comment

This post explains the steps to setup a simple JMS queue in Oracle WebLogic Server.

  1. Create weblogic domain. Let’s call it as JMSDomain
  2. Start JMSDomain from command prompt1
  3. Go to weblogic console from any of your favorite browser, http://localhost:7001/console
  4. In Domain Structure navigate to JMSDomain–>Services –>Messaging
  5. Click on ‘JMS Servers’2
  6. Create a new JMS Server3
  7. Click Next
  8. Select Target as ‘AdminServer’ (this is default in my case)4
  9. Click on Finish
  10. This should create JMS Server successfully and should show the status as running 5
  11. Now in the Domain Structure navigate to JMS Modules
  12. Click on New button6
  13. Click Next, select targets as ‘AdminServer’7
  14. Click ‘Next’ and Click ‘Finish’ button
  15. Now click on ‘AlertJMSModules’ this should navigate to ‘Settings for AlertJMSModules’ pane i.e. Summary of Resources
  16. Click on ‘New’ button for adding Connection Factory and Queue resource8
  17. Click Next to create connection factory9
  18. Click Finish, similarly follow the same 2 steps above to create queue.
  19. Your Summary of Resources should look something like this10
  20. That’s it! You now have a JMS Queue successfully configured
  21. Refer my next post for writing a Java client to access the queue configured…