Wednesday, November 25, 2009

Installing OES with WebLogic 11gR1

The below is not officially supported by Oracle yet, but I've been happily running OES under WebLogic 11gR1 and thought it might be useful information for others.

WebLogic Server 10.3 is the most recent version certified for use with OES is 10.1.4.3. If you want to run OES with WebLogic 11gR1 (also known as WebLogic 10.3.1) you will need to take a few extra steps.

1) install WebLogic 11gR1
2) run the DBConfig tool to create the database for OES
3) install OES 10.1.4.3 Admin Server
During the installation do not install the OES schema.
4) install the latest OES cumulative patch - currently CP2
to do this you unzip the patch, edit ApplyAdminPatch.bat or .sh and then run that script
5) run install_schema.bat or .sh depending on platform. This script no only creates all of the tables and indexes but it also loads the default set of policies and boots the server.


If you accidentally install the schema in step 3 it's easy enough to recover:
1) stop SCM and Admin server
2) unzip the latest CP
3) edit the ApplyAdminPatch.sh/.bat
4) apply the patch
5) run install_ales_schema.sh/.bat



Update on Dec 2, 2009: CP3 is now available.

Tuesday, November 24, 2009

Oracle Access Manager (OAM) and Directory Migration

At times it is necessary to reconfigure one or more of Oracle Access Manager’s directory configuration.

This post describes the recommended process and step-by-step configuration changes to Oracle Access Manager (OAM) required to make OAM utilize a different directory or directory configuration for user, configuration and policy storage.

This post does not address the migration of data between directories themselves. Rather, it focuses on the configuration changes required in OAM.

Also be aware that schema and tree changes can require additional considerations such as requiring changes to attribute access control policies and attribute mapping.

Overview

I recommend that during the process of modifying OAM directory configuration, users turn on directory logging/debugging sufficient enough to monitor all LDAP requests made from OAM to the directory.

If directory changes are being made to the user store and OAM policy/configuration stores then I recommend that OAM users first re-configure the user store by modifying the directory server profiles. I recommend that this change is tested and verified before moving on to modifying the policy/configuration store.

The process for modifying directory configuration in OAM mostly follows what is outlined in the OAM documentation on the subject. However, I would like to make the following clarifications:

1) Directory profile changes themselves are activated following a restart of the OAM services. Changes to directory configuration for policy and configuration storage require re-configuration of the appropriate components (Identity Server, Policy Server, and Access server).

2) In the re-configuration of the Access Server, customers should execute the start_configureAAAServer command with the ‘install’ option rather than the ‘reconfig’ option recommended in the doc. The reconfig option does not give you the opportunity to reconfigure directory configurations. The appropriate command on UNIX is as follows:
start_configureAAAServer install

Directory Profile Changes To Reflect User Store Changes

Directory profile changes can be made from either the Identity or Access System consoles. Directory profiles appear to be shared across OAM components and so only need to be changed in one place.

From the Identity System Console:
1. From the Identity System Console, click System Configuration.
2. On the System Configuration page, click Directory Profiles. The Configure Profiles page appears. The middle section of the page, under the heading Configure LDAP Directory Server Profiles, contains a list of configured directory server profiles.
3. Click the link for the directory server profile that you want to view. The Modify Directory Server Profile page appears.

From the Access System Console:
1. From the Access System Console, click System Configuration, then click Server settings. The View Server Settings page appears. This page displays the directory settings for configuration and policy storage, a link to modify those settings, and a listing of directory profiles with links to modify the profiles as well.
2. Click the link for the directory server profile that you want to view. The Modify Directory Server Profile page appears.

From the Modify Directory Server Profile page, simply make the modifications you desire and then restart all OAM services.

At this point I recommend that you do a test login to verify that the change worked and that users can now be successfully authenticated out of the modified Directory Profile (associated with a new or modified directory).

Modifying Policy and Configuration Data Directory Configuration
1. First modify the Directory Server Configuration in the Identity System Console.
a. From the Identity System Console, click System Configuration. On the System Configuration page, click Directory Profiles. The Configure Profiles page appears.
b. The top portion of Configure Profiles page shows details for the directory server that contains user data and configuration data. Click the Directory Server link to bring up the modification page.
c. Modify the page as you intend. Note that if you change the security, server, or port setting that you will have to rerun the Identity Server setup (see below).

2. Modify the Directory Server Configuration in the Access System Console.
a. From the Access System Console, click System Configuration, then click Server settings. The View Server Settings page appears.
b. Click the Directory Server link to bring up the modification page.
c. Note here that the page is divided into two sections. One section to configure the store for ‘configuration data’ and one section to configure the store for ‘policy data’. Many OAM users will make these the same but they can be different.
d. Modify the page as you intend. After making changes you will have to rerun the setup processes for the Policy and Access Servers (see below).

Rerun Setup for All Components
Rerun the setup of the Identity System, Policy Manager, and Access Server, in order, carefully following the instructions in the documentation (with one exception listed below):

http://download.oracle.com/docs/cd/E15217_01/doc.1014/e12489/idconfig.htm#BABIGBIG

After completing each component, I recommend that you restart that component and verify that on startup it is successfully pulling the appropriate data from the modified source.
As mentioned above, you need to execute the start_configureAAAServer command with the ‘install’ option rather than the ‘reconfig’ option recommended in the doc. The reconfig option does not give you the opportunity to reconfigure directory configurations. The appropriate command on UNIX is as follows:

start_configureAAAServer install

Friday, November 6, 2009

The new Oracle Entitlements Server (OES) and Oracle Web Services Manager (OWSM) 11g integration is finally here!

I know that a lot of people have been after me for this, so I want to apologize again for how long it has taken me to get this together (OOW + 3 weeks). But I hope people find it worth the wait.

This is essentially an update of some work that Kamlesh Patel did last year, so the basic design is really his idea.

OES-OWSM Integration FAQ


Question:Where can I get it?

Answer: I added to the OWSM 11g Custom Assertions Project on www.samplecode.oracle.com.

Question:What are the prerequisites?

Answer: You'll need an 11g SOA Suite Domain protected by an OES WLS SM. What I did for the OOW demo that makes things a lot simpler is use the OESAdjudicator. I talked a little about this approach previously. Basically, follow the steps I outline before except that instead of throwing the domain into discovery mode and figuring out the WLS resources, just add the OESAdjudicator to the domain. This basically eliminates the need for OES to protect the WLS resources.

Question: How do I build it?
Answer: You'll need to get the source code from svn. The details are here.
The src and the build are contained in the oes-owsm directory. You'll need to modify the build.xml file to point to the SOA home and OES home directories. From there, set-up you're environment (BEA_HOME/wlserver_10.3/server/bin/setWLSEnv.cmd) and then run ant. You should end-up with a file called oes-owsm.jar.

Question:Why do I need to know how to build it?

Answer:Because when you use it to protect a WLS Web Service, all of the configuration is contained in the META-INF/policies/samples/oes file, and this needs to be packed into the jar. I have not tested this custom assertion protecting SOA Composite Web Services

Question: What can I configure in the META-INF/policies/samples/oes file?

Answer: Let's take a look at the file



<wsp:Policy xmlns="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:orasp="http://schemas.oracle.com/ws/2006/01/securitypolicy"
orawsp:status="enabled" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" orawsp:category="security" orawsp:attachTo="binding.server" wsu:Id="oes_authorization_policy"
xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
wsp:Name="sample/oes">

<orasp:oes orawsp:Silent="true" orawsp:Enforced="true" orawsp:name="OES Authorization" orawsp:category="security/authorization">
<orawsp:bindings>
<orawsp:Implementation>com.oracle.oes.owsm.sample.Assertion</orawsp:Implementation>
<orawsp:Config orawsp:name="oes" orawsp:configType="declarative">
<orawsp:PropertySet orawsp:name="OES RMI SSM Settings">
<orawsp:Property orawsp:name="ConfigDirectory" orawsp:type="string" orawsp:contentType="required">
<orawsp:Value>c:/bea/ales32-admin/rmi-ssm/instance/rmissm/pdpproxy</orawsp:Value>
</orawsp:Property>
<orawsp:Property orawsp:name="ConfigID" orawsp:type="string" orawsp:contentType="required">
<orawsp:Value>soa_suite_domain2</orawsp:Value>
</orawsp:Property>
<orawsp:Property orawsp:name="AuthenticationRequired" orawsp:type="boolean" orawsp:contentType="required">
<orawsp:Value>false</orawsp:Value>
</orawsp:Property>
</orawsp:PropertySet>
<orawsp:PropertySet orawsp:name="OES Identity Assertion Settings">
<orawsp:Property orawsp:name="InternalAssertion" orawsp:type="boolean" orawsp:contentType="required">
<orawsp:Value>false</orawsp:Value>
</orawsp:Property>
<orawsp:Property orawsp:name="OWSMIdentity" orawsp:type="string" orawsp:contentType="required">
<orawsp:Value>OWSM</orawsp:Value>
</orawsp:Property>
</orawsp:PropertySet>
<orawsp:PropertySet orawsp:name="OES Authorization Settings">
<orawsp:Property orawsp:name="Application" orawsp:type="string" orawsp:contentType="required">
<orawsp:Value>owsm</orawsp:Value>
</orawsp:Property>
<orawsp:Property orawsp:name="Resource" orawsp:type="string" orawsp:contentType="required">
<orawsp:Value>oow2009demo</orawsp:Value>
</orawsp:Property>
<orawsp:Property orawsp:name="LookupAction" orawsp:type="string" orawsp:contentType="required">
<orawsp:Value>lookup</orawsp:Value>
</orawsp:Property>
<orawsp:Property orawsp:name="ExecuteAction" orawsp:type="string" orawsp:contentType="required">
<orawsp:Value>execute</orawsp:Value>
</orawsp:Property>
</orawsp:PropertySet>
</orawsp:Config>
</orawsp:bindings>
</orasp:oes>
</wsp:Policy>

There are only a few properties that you need to really care about. ConfigID is the name of the realm that WLS is running - I think the configTool makes it the domain name, but look in config.xml just to be sure. Application and Resource are concatenated together to make up the prefix for the resource in OES. Example: //app/policy//owsm/oow2009/model object name/port name

Question: How do I install it?

Answer: Copy the oes-owsm.jar to the DOMAIN_HOME/lib directory, and restart the server.

Question: How do I bind it to a webservice?

Answer: You add it to policy just like any other WLS Web-Services policy. Either through the WLS console or through the @Policy annotation. Note: You need to configure an additional policy that does the actual authentication, like one of the SAML policies. The assertion assumes that the user is already authenticated. Also, again I haven't tested it attaching it to a SOA composite, but if some one wants to try, I'll support the effort ;)

Question: How do I author an OES policy using it?
Answer: Take a look at the policies from my OOW demo



I modeled it as a two step process (I could have just as easily passed down the entire SOAP message to the WLS SM, like I did in the OES-BPEL integration, but I think for most in-bound authorization cases, I like this model). In the first step, the assertion calls OES with the lookup action. If it succeeds, it processes the responses in an interesting way. If the response has a name of namespace then it sets uses it as the target name space for the XPathQuery. If its anything else, then the Assertion assumes that the name of the response is a dynamic attribute, and the value is an XPathQuery that the assertion should run to populate the attributes.

In the example for OOW, there are two responses from the lookup. One to get the value of the CCType in the body and add it to the variable oow_cc_type. The other is pulling the value of the attribute title from the AttributeStatement from the SAML Assertion (basically, the user's title) and sets it in the oow_title attribute.

The execute action gets called next and basically, as you can see from the example, passes in the values it got from the lookup XPATHQuery.

Question: What do I do if I want to use a namespace other than tns,env, or saml?

Answer: You need to add it to modify the AssertionNamespaceContext.java to handle the namespace. The code is pretty simple.



public String getNamespaceURI(String prefix) {
System.out.println("Looking for the namespace for prefix: "+prefix);

if (prefix.equals("env")) {

return "http://schemas.xmlsoap.org/soap/envelope/";

} else if (prefix.equals("saml")) {

return "urn:oasis:names:tc:SAML:1.0:assertion";

}

return theNamespace;
}

So What Next?


I added the project (like most of my stuff from the blog) to http://soa-security.samplecode.oracle.com. Try this out, and let me know what you think, but also, this integration could be enhanced in a number of ways. Examples:

  • What should OES do when filtering the response?
  • What could OES do with responses if it knew that the Web Service has a DataControl (i.e. SOAP Message contains a query)?

The source is out there, so I'm hoping people will add their own contributions. Basically, I hope that I've taught you how to fish. If you are starving, just post a comment here, and we'll throw you a fish stick :)

Wednesday, November 4, 2009

WebLogic Server (WLS) to Oracle Service Bus (OSB) to WebLogic Server using SAML Sender Vouches - Active/Active

In yesterday's post on WLS to OSB to WLS with SAML Sender Vouches, OSB was not really acting as a full "active-intermediary". Basically, OSB was validating the SAML Assertion on the request and sending a new request with a new SAML Assertion to the business-service. The response from the business service (though signed) was ignored by OSB. The signature is validated by the sender. Let's for the sake of discussion call this configuration active/passive security. This model works if:

  • You are basically interesting in using OSB to authorize the use of services
  • You are not doing any transformations on the response (you'll break the signature).
  • The producer and consumer trust each other directly. This is different then they each trust the service bus.


If your deployment meets this criteria, then "Bob's Your Uncle" (I'm from Massachusetts, not California, so I'm not sure I used that right - but basically I'm saying "you're good")

If not, then read on. These are the gory details of getting this scenario to work in active/active. I'm not going to cover everything from yesterday, I'll just get down to the brass tacks of the policies.

Direction.In (Request)



Direction.Out (Response)



Configuring the WLS Service Producer


Since this is a use case primarily about processing the response, let's start with the response coming back from the service producer. OSB cannot handle <ProtectTokens> policy assertions because it does not support the STR Transform that WLS uses to generate the signature. So, this assertion has to be removed from the standard Wssp1.2-2007-Saml1.1-SenderVouches-Wss1.0.xml.

Configuring the Business Service


A nuance of the way that OSB enforces policy is that the entire message is processed - signatures validated, messages decrypted - and then the policy is checked to see if it complies. The policy is basically a minimum that has to be met - not a prescription for how to validate the message. The idea of the "Empty" policy is to just have OSB process the signature that the Service Producer generated. There are no other conditions.

Configuring the Proxy Service


The message now needs to be signed by OSB. The pre-configured Sign.xml will work just fine.

Configuring WLS Service Consumer


You need to use two different policies for the JAX-WS client. Since the signature generated by OSB does not conform with the standard policy in two ways - it does not protect the tokens (sign) and it does include the RAW X.509 Certificate as opposed to an reference by Issuer Serial Number. So, the policy for the outputMessage (outbound) is a custom policy very similar to the in-bound policy on the service consumner, except that we have to additionally allow for the Recipient Token to be passed. The policy for the inputMessage (inbound) is the standard Wssp1.2-2007-Saml1.1-SenderVouches-Wss1.0.xml. The code looks like this:


ClientPolicyFeature cpf =
new ClientPolicyFeature();

InputStreamPolicySource ps_out = new InputStreamPolicySource(this.getServletContext().getResourceAsStream("/WEB-INF/policy-no-protect-plus-recipient-token.xml"));
InputStreamPolicySource ps_in = new InputStreamPolicySource(this.getServletContext().getResourceAsStream("/WEB-INF/policy.xml"));

cpf.setEffectivePolicyForInputMessage(ps_in);
cpf.setEffectivePolicyForOutputMessage(ps_out);

Dispatch<SOAPMessage> dispatch = service.createDispatch(portName,
SOAPMessage.class, Service.Mode.MESSAGE, new WebServiceFeature[] {cpf});



SOAPMessage response = dispatch.invoke(request);


Policies


Wssp1.2-2007-Saml1.1-SenderVouches-Wss1.0.xml minus ProtectTokens



<?xml version="1.0" encoding="windows-1252" ?>
<wsp:Policy wssutil:Id="Wssp1.2-2007-Saml1.1-SenderVouches-Wss1.0.xml" xmlns:wssutil="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<ns1:AsymmetricBinding xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns1:InitiatorToken>
<wsp:Policy>
<ns1:X509Token ns1:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<ns1:WssX509V3Token10 />
</wsp:Policy>
</ns1:X509Token>
</wsp:Policy>
</ns1:InitiatorToken>
<ns1:RecipientToken>
<wsp:Policy>
<ns1:X509Token ns1:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">

<wsp:Policy>
<ns1:WssX509V3Token10 />
</wsp:Policy>
</ns1:X509Token>
</wsp:Policy>
</ns1:RecipientToken>
<ns1:AlgorithmSuite>
<wsp:Policy>
<ns1:Basic256 />
</wsp:Policy>
</ns1:AlgorithmSuite>
<ns1:Layout>
<wsp:Policy>
<ns1:Lax />
</wsp:Policy>
</ns1:Layout>
<ns1:IncludeTimestamp />

<!-- OSB does not work well with this assertion
<ns1:ProtectTokens />
-->

<ns1:OnlySignEntireHeadersAndBody />
</wsp:Policy>
</ns1:AsymmetricBinding>
<ns2:SignedSupportingTokens xmlns:ns2="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns2:SamlToken ns2:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<ns2:WssSamlV11Token10 />
</wsp:Policy>
</ns2:SamlToken>
</wsp:Policy>
</ns2:SignedSupportingTokens>
<ns3:Wss10 xmlns:ns3="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns3:MustSupportRefKeyIdentifier />
<ns3:MustSupportRefIssuerSerial />

</wsp:Policy>
</ns3:Wss10>
</wsp:Policy>


Wssp1.2-2007-Saml1.1-SenderVouches-Wss1.0.xml minus ProtectTokens plus Include Recipient Token



<?xml version="1.0" encoding="windows-1252" ?>
<wsp:Policy wssutil:Id="Wssp1.2-2007-Saml1.1-SenderVouches-Wss1.0.xml" xmlns:wssutil="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<ns1:AsymmetricBinding xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns1:InitiatorToken>
<wsp:Policy>
<ns1:X509Token ns1:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<ns1:WssX509V3Token10 />
</wsp:Policy>
</ns1:X509Token>
</wsp:Policy>
</ns1:InitiatorToken>
<ns1:RecipientToken>
<wsp:Policy>
<ns1:X509Token ns1:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToInitiator">

<wsp:Policy>
<ns1:WssX509V3Token10 />
</wsp:Policy>
</ns1:X509Token>
</wsp:Policy>
</ns1:RecipientToken>
<ns1:AlgorithmSuite>
<wsp:Policy>
<ns1:Basic256 />
</wsp:Policy>
</ns1:AlgorithmSuite>
<ns1:Layout>
<wsp:Policy>
<ns1:Lax />
</wsp:Policy>
</ns1:Layout>
<ns1:IncludeTimestamp />

<!-- OSB does not work well with this assertion
<ns1:ProtectTokens />
-->

<ns1:OnlySignEntireHeadersAndBody />
</wsp:Policy>
</ns1:AsymmetricBinding>
<ns2:SignedSupportingTokens xmlns:ns2="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns2:SamlToken ns2:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<ns2:WssSamlV11Token10 />
</wsp:Policy>
</ns2:SamlToken>
</wsp:Policy>
</ns2:SignedSupportingTokens>
<ns3:Wss10 xmlns:ns3="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns3:MustSupportRefKeyIdentifier />
<ns3:MustSupportRefIssuerSerial />

</wsp:Policy>
</ns3:Wss10>
</wsp:Policy>




Empty Policy



<?xml version="1.0"?>

<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wssp="http://www.bea.com/wls90/security/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wls="http://www.bea.com/wls90/security/policy/wsee#part"
wsu:Id="validate-bs-response"
>


<wssp:MessageAge/>

</wsp:Policy>

Sender Vouches plus Sign Timestamp



<?xml version="1.0"?>

<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wssp="http://www.bea.com/wls90/security/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wls="http://www.bea.com/wls90/security/policy/wsee#part"
wsu:Id="saml-policy-to-business-service"
>

<wssp:Identity>
<wssp:SupportedTokens>
<wssp:SecurityToken TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-2004-01-saml-token-profile-1.0#SAMLAssertionID">
<wssp:Claims>
<wssp:ConfirmationMethod>sender-vouches</wssp:ConfirmationMethod>
</wssp:Claims>
</wssp:SecurityToken>
</wssp:SupportedTokens>
</wssp:Identity>

<wssp:Integrity>

<wssp:SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<wssp:CanonicalizationAlgorithm
URI="http://www.w3.org/2001/10/xml-exc-c14n#"/>

<wssp:Target>
<wssp:DigestAlgorithm
URI="http://www.w3.org/2000/09/xmldsig#sha1" />
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()
</wssp:MessageParts>
</wssp:Target>

<wssp:Target>
<wssp:DigestAlgorithm
URI="http://www.w3.org/2000/09/xmldsig#sha1" />
<wssp:MessageParts
Dialect="http://www.w3.org/TR/1999/REC-xpath-19991116">
wsp:GetHeader(./wsse:Security/wsu:Timestamp)
</wssp:MessageParts>
</wssp:Target>

<wssp:Target>
<wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1" />
<wssp:MessageParts
Dialect="http://www.bea.com/wls90/security/policy/wsee#part">
wls:SecurityHeader(Assertion)
</wssp:MessageParts>
</wssp:Target>

</wssp:Integrity>

<!--
<wssp:Confidentiality>

<wssp:KeyWrappingAlgorithm URI="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>

<wssp:Target>
<wssp:EncryptionAlgorithm
URI="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<wssp:MessageParts
Dialect="http://www.bea.com/wls90/security/policy/wsee#part">
wls:SecurityHeader(Assertion)
</wssp:MessageParts>
</wssp:Target>

<wssp:Target>
<wssp:EncryptionAlgorithm
URI="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()</wssp:MessageParts>
</wssp:Target>

<wssp:KeyInfo />
</wssp:Confidentiality>
-->

<wssp:MessageAge/>

</wsp:Policy>

<wssp:MessageAge/>

</wsp:Policy>

Standard OSB SAML Sender Vouches



<?xml version="1.0"?>

<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wssp="http://www.bea.com/wls90/security/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wls="http://www.bea.com/wls90/security/policy/wsee#part"
wsu:Id="saml-policy"
>

<wssp:Identity>
<wssp:SupportedTokens>
<wssp:SecurityToken TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-2004-01-saml-token-profile-1.0#SAMLAssertionID">
<wssp:Claims>
<wssp:ConfirmationMethod>sender-vouches</wssp:ConfirmationMethod>
</wssp:Claims>
</wssp:SecurityToken>
<!--
<wssp:SecurityToken TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
-->
</wssp:SupportedTokens>
</wssp:Identity>

<wssp:Integrity>

<wssp:SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<wssp:CanonicalizationAlgorithm
URI="http://www.w3.org/2001/10/xml-exc-c14n#"/>

<wssp:Target>
<wssp:DigestAlgorithm
URI="http://www.w3.org/2000/09/xmldsig#sha1" />
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()
</wssp:MessageParts>
</wssp:Target>


<wssp:Target>
<wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1" />
<wssp:MessageParts
Dialect="http://www.bea.com/wls90/security/policy/wsee#part">
wls:SecurityHeader(Assertion)
</wssp:MessageParts>
</wssp:Target>


</wssp:Integrity>

<!--
<wssp:Confidentiality>

<wssp:KeyWrappingAlgorithm URI="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>

<wssp:Target>
<wssp:EncryptionAlgorithm
URI="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<wssp:MessageParts
Dialect="http://www.bea.com/wls90/security/policy/wsee#part">
wls:SecurityHeader(Assertion)
</wssp:MessageParts>
</wssp:Target>

<wssp:Target>
<wssp:EncryptionAlgorithm
URI="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()</wssp:MessageParts>
</wssp:Target>

<wssp:KeyInfo />
</wssp:Confidentiality>
-->

<wssp:MessageAge/>

Tuesday, November 3, 2009

WebLogic Server (WLS) to Oracle Service Bus (OSB) to WebLogic Server using SAML Sender Vouches

I'm sure many people were hoping that the next post would be the much anticipated OES-OWSM Custom Assertion, but things have been very busy coming out of Open World. Oddly, I'm working with multiple customers that have been looking for a solution to the following use case:

WLS makes a Web-Services call using JAX-WS to Oracle Service Bus (OSB) passing the identity of the caller using SAML Sender Vouches (SV). OSB serves as an active-intermediary and process the SAML Assertion. OSB then goes and calls a Business Service propagating the user's identity, again using SAML SV.

What makes this use case a little tricky is that OSB at present does not understand WS-Policy 1.2 Assertions, and the JAX-WS stack on WLS does not understand the OSB proprietary assertions. This means that local policy needs to be applied 4 places

  • JAX-WS Client using WS-Policy 1.2
  • OSB Proxy Service using OSB Policy
  • OSB Business Service using OSB Policy
  • WLS Web Services service using WS-Policy 1.2


This post will cover the specific policies and how to apply them at each point.

JAX-WS Client using WS-Policy 1.2



You need to use a ClientPolicyFeature, and load the actual policy from an InputStream. In the example below, I'm running inside a web-application and packaged the policy.xml in the WEB-INF directory.


ClientPolicyFeature cpf =
new ClientPolicyFeature();



InputStreamPolicySource ps = new InputStreamPolicySource(this.getServletContext().getResourceAsStream("/WEB-INF/policy.xml"));

cpf.setEffectivePolicy(ps);


Dispatch dispatch = service.createDispatch(portName,
SOAPMessage.class, Service.Mode.MESSAGE, new WebServiceFeature[] {cpf});




The policy that I'm using is just the standardWssp1.2-2007-Saml1.1-SenderVouches-Wss1.0.xml.


<?xml version="1.0" encoding="windows-1252" ?>
<wsp:Policy wssutil:Id="Wssp1.2-2007-Saml1.1-SenderVouches-Wss1.0.xml" xmlns:wssutil="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<ns1:AsymmetricBinding xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns1:InitiatorToken>
<wsp:Policy>
<ns1:X509Token ns1:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<ns1:WssX509V3Token10 />
</wsp:Policy>
</ns1:X509Token>
</wsp:Policy>
</ns1:InitiatorToken>
<ns1:RecipientToken>
<wsp:Policy>
<ns1:X509Token ns1:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">

<wsp:Policy>
<ns1:WssX509V3Token10 />
</wsp:Policy>
</ns1:X509Token>
</wsp:Policy>
</ns1:RecipientToken>
<ns1:AlgorithmSuite>
<wsp:Policy>
<ns1:Basic256 />
</wsp:Policy>
</ns1:AlgorithmSuite>
<ns1:Layout>
<wsp:Policy>
<ns1:Lax />
</wsp:Policy>
</ns1:Layout>
<ns1:IncludeTimestamp />

<ns1:ProtectTokens />
<ns1:OnlySignEntireHeadersAndBody />
</wsp:Policy>
</ns1:AsymmetricBinding>
<ns2:SignedSupportingTokens xmlns:ns2="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns2:SamlToken ns2:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<ns2:WssSamlV11Token10 />
</wsp:Policy>
</ns2:SamlToken>
</wsp:Policy>
</ns2:SignedSupportingTokens>
<ns3:Wss10 xmlns:ns3="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns3:MustSupportRefKeyIdentifier />
<ns3:MustSupportRefIssuerSerial />

</wsp:Policy>
</ns3:Wss10>
</wsp:Policy>

On the client, beside setting up the policy, you'll also need to configure a SAMLCredentialMapper and a PKICredentialMapper. The PKICredentialMapper needs to have access to a keystore that contains the Private Key used to sign the request.

OSB Proxy Service using OSB Policy


The OSB policy is really just the WLS 9.2 Web Services stack.. Basically, you need to create a WS-Policy and attach it to the request in the proxy service. Also, need to make sure to configure the proxy service to process the WS-Security header.




The actual policy is below.

<?xml version="1.0"?>

<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wssp="http://www.bea.com/wls90/security/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wls="http://www.bea.com/wls90/security/policy/wsee#part"
wsu:Id="saml-policy"
>

<wssp:Identity>
<wssp:SupportedTokens>
<wssp:SecurityToken TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-2004-01-saml-token-profile-1.0#SAMLAssertionID">
<wssp:Claims>
<wssp:ConfirmationMethod>sender-vouches</wssp:ConfirmationMethod>
</wssp:Claims>
</wssp:SecurityToken>
</wssp:SupportedTokens>
</wssp:Identity>

<wssp:Integrity>

<wssp:SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<wssp:CanonicalizationAlgorithm
URI="http://www.w3.org/2001/10/xml-exc-c14n#"/>

<wssp:Target>
<wssp:DigestAlgorithm
URI="http://www.w3.org/2000/09/xmldsig#sha1" />
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()
</wssp:MessageParts>
</wssp:Target>

<wssp:Target>
<wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1" />
<wssp:MessageParts
Dialect="http://www.bea.com/wls90/security/policy/wsee#part">
wls:SecurityHeader(Assertion)
</wssp:MessageParts>
</wssp:Target>

</wssp:Integrity>


<wssp:MessageAge/>

</wsp:Policy>



Setting up OSB to consume the SAML Assertion and validate the signature requires the creation of a SAML Identity Asserter. NOTE: In the asserting party configuration, OSB uses a relative path Remember this if you run into trouble getting OSB to understand the assertion.

OSB Business Service using OSB Policy


This was really the only "tricky" part. I had to modify the saml-sv policy to sign the timestamp. The policy on the business service doesn't require it, but it does expect the Timestamp to have a wsu:Id, and making OSB sign it does exactly that. The set-up in OSB is the same as the proxy service, just configure the policy on the request.

The policy on the business service is as follows:


<?xml version="1.0"?>

<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wssp="http://www.bea.com/wls90/security/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wls="http://www.bea.com/wls90/security/policy/wsee#part"
wsu:Id="saml-policy-to-business-service"
>

<wssp:Identity>
<wssp:SupportedTokens>
<wssp:SecurityToken TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-2004-01-saml-token-profile-1.0#SAMLAssertionID">
<wssp:Claims>
<wssp:ConfirmationMethod>sender-vouches</wssp:ConfirmationMethod>
</wssp:Claims>
</wssp:SecurityToken>
</wssp:SupportedTokens>
</wssp:Identity>

<wssp:Integrity>

<wssp:SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<wssp:CanonicalizationAlgorithm
URI="http://www.w3.org/2001/10/xml-exc-c14n#"/>

<wssp:Target>
<wssp:DigestAlgorithm
URI="http://www.w3.org/2000/09/xmldsig#sha1" />
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()
</wssp:MessageParts>
</wssp:Target>

<wssp:Target>
<wssp:DigestAlgorithm
URI="http://www.w3.org/2000/09/xmldsig#sha1" />
<wssp:MessageParts
Dialect="http://www.w3.org/TR/1999/REC-xpath-19991116">
wsp:GetHeader(./wsse:Security/wsu:Timestamp)
</wssp:MessageParts>
</wssp:Target>

<wssp:Target>
<wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1" />
<wssp:MessageParts
Dialect="http://www.bea.com/wls90/security/policy/wsee#part">
wls:SecurityHeader(Assertion)
</wssp:MessageParts>
</wssp:Target>

</wssp:Integrity>

<wssp:MessageAge/>

</wsp:Policy>



When adding a business service that requires signing, the proxy service has to have a Service Key Provider. This is really just a wrapper around the policies stored in the PKI Mapper. Basically, you select an alias to use to sign the message going to that business service.



Inside of the realm, in order to be able to configure a Service Key Provider, the PKI CredMapper needs to exist. In addition, the SAML Credential Mapper is required to generate the SAML Assertion.

WLS Web Services service using WS-Policy 1.2


This is pretty straight forward.



@WebService
@Policy(uri = "policy:Wssp1.2-2007-Saml1.1-SenderVouches-Wss1.0.xml")
public class Test {


public String hello(String in) {
System.out.println("=====>"+in);
return "Hello "+in;
}

}



Summary


In setting up a scenario as complicated as this there will undoubtedly be challenges. Use the debug settings inside of WLS, they are your friend. In my set-up I added the following JAVA_OPTIONS to my setDomainEnv.cmd


set JAVA_OPTIONS=%JAVA_OPTIONS% %JAVA_PROPERTIES% -Dwlw.iterativeDev=%iterativeDevFlag% -Dwlw.testConsole=%testConsoleFlag% -Dwlw.logErrorsToConsole=%logErrorsToConsoleFlag%
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.wsee.verbose=* -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true -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
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.xml.crypto.wss.debug=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.xml.crypto.wss.verbose=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.xml.crypto.keyinfo.debug=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.xml.crypto.keyinfo.verbose=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.xml.crypto.dsig.debug=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.xml.crypto.dsig.verbose=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.xml.crypto.encrypt.debug=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.xml.crypto.encrypt.verbose=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.servlet.DIEnabled=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.debug.DebugSecuritySAMLService=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.debug.DebugSecuritySAMLCredMap=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.debug.DebugSecuritySAMLAtn=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.debug.DebugSecuritySAMLLib=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.debug.DebugSecuritySAML2Service=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.debug.DebugSecuritySAML2CredMap=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.debug.DebugSecuritySAML2Atn=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.debug.DebugSecuritySAML2Lib=true
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.debug.DebugSecurityCredMap=true


This gives you good visibility into where the issues are. Also can't hurt to have the weblogic.security.atn and weblogic.security.credmap debug categories on. When trying to figure out what is going on, more information is better. Be patient, this will spit out a lot of information, but look through it and you can normally get to the issue.