Wednesday, September 9, 2009

OWSM Client Policies and SAML - Simpler is Better

Classic example of me being "too clever by half".

From the OWSM Documentation

Looks like you can just set the username as a property


URL localURL =
new URL("https://.../MyWebServicePort?WSDL");

QName name = new QName("http://view.team2.oracle.com/","MyWebServiceService");

myWebServiceService =
new MyWebServiceService(localURL,name);

final weblogic.wsee.jws.jaxws.owsm.SecurityPolicyFeature securityFeature =
new weblogic.wsee.jws.jaxws.owsm.SecurityPolicyFeature("policy:oracle/wss_saml_token_bearer_over_ssl_client_policy");

WebServiceFeature[] features =
new WebServiceFeature[] {securityFeature};

MyWebService myWebService =
myWebServiceService.getMyWebServicePort(features);


Map<String,Object> reqContext = ((BindingProvider) myWebService).getRequestContext();
reqContext.put( BindingProvider.USERNAME_PROPERTY, "jdoe");


// Add your code to call the desired methods.
System.out.println(myWebService.helloThere("From a Java client - JDOE"));



This "AH HA" eliminates the need for the code to get the JAAS Subject and the configuration of the jps-config.xml and system-jazn-data.xml. Much better.

Just to round out, here is the client for SAML sender-vouches.


URL localURL = new URL("http://oamwindows:7001/Team2-ViewController-context-root/MyWebServicePort?WSDL");

QName name = new QName("http://view.team2.oracle.com/","MyWebServiceService");

myWebServiceService =
new MyWebServiceService(localURL,name);

final weblogic.wsee.jws.jaxws.owsm.SecurityPolicyFeature securityFeature =
new weblogic.wsee.jws.jaxws.owsm.SecurityPolicyFeature("policy:oracle/wss10_saml_token_with_message_integrity_client_policy");

WebServiceFeature[] features =
new WebServiceFeature[] {securityFeature};

MyWebService myWebService =
myWebServiceService.getMyWebServicePort(features);

Map<String,Object> reqContext = ((BindingProvider) myWebService).getRequestContext();
reqContext.put( BindingProvider.USERNAME_PROPERTY, "jdoe");


reqContext.put(ClientConstants.WSSEC_KEYSTORE_LOCATION, "c:/wstest/alice.jks");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_PASSWORD, "password" );
reqContext.put(ClientConstants.WSSEC_SIG_KEY_ALIAS, "alice" );
reqContext.put(ClientConstants.WSSEC_KEYSTORE_TYPE, "JKS" );
reqContext.put(ClientConstants.WSSEC_SIG_KEY_PASSWORD, "password" );
reqContext.put(ClientConstants.WSSEC_ENC_KEY_ALIAS, "alice" );
reqContext.put(ClientConstants.WSSEC_ENC_KEY_PASSWORD, "password" );
reqContext.put(ClientConstants.WSSEC_RECIPIENT_KEY_ALIAS,"bob");

System.out.println(myWebService.helloThere("From a Java client"));



I did all of my testing with the demo CA that ships with WebLogic Server. I find the CertGen and the ImportPrivateKey
tools to be really useful in building small samples. I created two keystores - alice.jks and bob.jks. Alice for the client and Bob for the server. This is all standard stuff, but one thing to remember that OWSM has only a single identity and trust store...not separate stores as in J2SE or WLS, so I had to add the CertGenCA.der to both keystores.

Beyond on that, really pretty simple. I configured the bob.jks keystore for the WebLogic Server Domain from EM - Domain (Right Click) -> Security -> Security Provider Configuration. Scroll down to Keystore...configure bob.jks as the store. Restart the server. Send the message and it just works!

OWSM stand-alone Client to OWSM Server doing SAML Bearer and SAML Sender-Vouches - check!

Tuesday, September 8, 2009

SAML Bearer Confirmation - An example using OWSM Client Policy

This is an extension of the discussion started by Brian in his inaugural post here at the FusionSecurity blog. Brian and I, along with other members of the A-Team were out at HQ getting some training on the SOA Security capabilities in 11g, and I wanted to share a useful "How-To" from that week.

First, let me show you the code, and then I'll take you through the code in some details and explain the additional set-up required to make this use case work. Basically, the code is for a stand-alone Java client using OWSM client policies to enable a JAX-WS Web Service Proxy to use SAML Bearer over SSL - quite a mouthful!

The Code


package com.oracle.team2.view;

import java.net.URL;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginContext;
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.WebServiceRef;
import oracle.security.jps.JpsContext;
import oracle.security.jps.JpsContextFactory;
import oracle.security.jps.service.login.LoginService;

public class MyWebServicePortClient {
@WebServiceRef
private static MyWebServiceService myWebServiceService;


public static void main(String[] args) throws Exception {

URL localURL =
new URL("https://.../MyWebServicePort?WSDL");

QName name =
new QName("http://view.team2.oracle.com/", "MyWebServiceService");

myWebServiceService = new MyWebServiceService(localURL, name);


JpsContextFactory factory =
JpsContextFactory.getContextFactory();

JpsContext jpsContext = factory.getContext("Client");
LoginService loginService =
jpsContext.getServiceInstance(LoginService.class);


CallbackHandler cbh = new MyAssertionCallbackHandler("josh");

String[] selectiveModules = new String[] {
"user.assertion.loginmodule"
};
LoginContext ctx =
loginService.getLoginContext(new Subject(), cbh, selectiveModules);
ctx.login();
Subject s = ctx.getSubject();

final weblogic.wsee.jws.jaxws.owsm.SecurityPolicyFeature securityFeature =
new weblogic.wsee.jws.jaxws.owsm.SecurityPolicyFeature(
"policy:oracle/wss_saml_token_bearer_over_ssl_client_policy");


Subject theSubject =
Subject.getSubject(AccessController.getContext());

System.out.println("The Subject is " + theSubject);


AccessControlContext acc =
AccessController.getContext();

Subject.doAs(s, new PrivilegedAction() {


public Object run() {
WebServiceFeature[] features =
new WebServiceFeature[] { securityFeature };

MyWebService myWebService =
myWebServiceService.getMyWebServicePort(features);

// Add your code to call the desired methods.
System.out.println(
myWebService.helloThere("From a Java client"));

return "done";
}
});

}
}


The Explanation



We're applying OWSM client side policy, that requires a SAML Assertion - Bearer and that the request is over SSL. The SSL implementation is the standard J2SE and OWSM uses the JAAS Subject for the identity. The policy is applied via the WebServiceFeature and is described in the OWSM documentation.

Basically, we're using OPSS inside of a J2SE client to establish the JAAS Subject, without providing a password. I used the OPSS documentation as a reference. I used exactly the MyAssertionCallbackHandler from the documentation.

The final "trick" is that the call to the web service is done inside of a call to Subject.doAs(Subejct,PriviledgedAction). This pushes the Subject from the LoginModule on to call stack, and makes it available for the OWSM policy.

The Configuration


So, there a few command line arguments that need to be passed to this client:

-Djavax.net.ssl.trustStore=truststore -Djavax.net.ssl.trustStorePassword=123456

There are the standard J2SE SSL parameters. The JAX-WS client uses the standard SSL.
In my example, I just used the DemoIdentity and DemoTrust, so I set my -D's to

-Djavax.net.ssl.trustStore=C:\\Oracle\\Middleware\\wlserver_10.3\\server\\lib\\DemoTrust.jks -Djavax.net.ssl.trustStorePassword=DemoTrustKeyStorePassPhrase

You also have to pass the program the location of the jps-config.xml.

-Doracle.security.jps.config=c:\jps-config-jse.xml

The jps-config.xml defines the Oracle Platform Security (OPSS) services used by the client. In our use-case, we're going to be using the LoginService to establish an identity for the client. I got the basis of the jps-config-jse.xml from DOMAIN_HOME\config\fmwconfig\jps-config.jse.xml.

At the end of this file, you need to add a jpsContext called Client that contains a reference to the user.assertion.loginmodule


<jpsContext name="Client">
<serviceInstanceRef ref="user.assertion.loginmodule"/>
</jpsContext>


The user assertion login module allows the client to create an identity for the user with no password. It won't work with any username - the user still has to be found in the identity store, which in this case is stored inside of the system-jazn-data.xml. By default, the login module is looking for the system-jazn-data.xml found in the same directory in the jps-config.xml.

I found the system-jazn-data.xml reference useful in building this file:


<jazn-data>
<jazn-realm>
<realm>
<name>jazn.com</name>
<users>
<user>
<name>josh</name>
<guid>1</guid>
</user>
</users>
</realm>
</jazn-realm>
</jazn-data>


The final, configuration step is to make sure that the user that you're asserting - in this case "josh" exists on the server side in WLS. You can just add the user via the WLS admin console.

The Wrap Up


This is definitely a little tricky, but it demonstrates how to use a SAML Bearer assertion. There is no PKI required on the client side - simply the ability to trust the server at the transport level. This is pretty straight forward and simpler then setting-up either sender-vouches or holder-of-key. Consider using this type of approach from within a trusted network.

Thursday, September 3, 2009

Bearer Confirmation Method (Huh! What is it good for…)


For starters, allow me to introduce myself. My name is Brian Eidelman and I am a new member of the Fusion Middleware Architecture Group (a.k.a the A-Team) and a new contributor to this blog. Since the memo has gone out that in addition to security we will be discussing dogs now, I'd like to introduce my faithful companion Coco.

Now without further ado, my post:

The WSS SAML Token Profile Specification defines several “confirmation methods” by which the contents of the SAML assertion can be linked to the SOAP message content itself. In other words the method of proving that the assertion really goes with the message that it is being sent in.

The “bearer” confirmation method is sort of peculiar in that it defines no process at all for proving the link between the contents of the assertion and the message content. Rather, the link is to be implicitly trusted.

At this point you may be saying to yourself, if there is no means of verifying that the SAML assertion goes with the message, then what good is it?

Well, the trust can be implicit for any number of reasons. It could just be that trusting developers created the service. More likely however, the link between the SAML assertion and the message can be implicitly trusted by the service because the integrity of the link has been delegated to some other external factor; usually to the network level.

In some cases we could be talking about an internal network setup so that all requests to the service are guaranteed to come from a tamper proof trusted client (if you aren’t buying into this, just humor me). In other cases we could be talking about SSL with 2-way authentication. The point is that the service can trust that only a proper trusted client can successfully get a message to it in the first place.

Now at this point you might be thinking to yourself, fine but then how is SAML with bearer confirmation different than just including a username token with no password in the message header.
Well, SAML with bearer confirmation offers a few additional advantages over the plain old username token. Foremost, the assertion can contain not just a username (subject) but also a bundle of attributes that can further serve to identify the user, define a users’ roles, or be otherwise consumed by the service. In addition, the assertion does capture the notion of what entity is “issueing” the assertion (asserting the user identity). Lastly, some SOA stacks may not be able to handle a username token with no password.

So after all that, what is the bearer confirmation good for? Given that it allows us to utilize assertions without the hassles and costs that come with the signing and key references that are a part of the other confirmation methods, bearer is the perfect confirmation method for basic identity propagation to or between internal services. A similar use case where bearer may fit the bill is identity propagation from trusted intermediary that maybe be doing the real authentication to the service over a securely established network connection.

Even the Longest Journey Starts with the Smallest Step - OpenAz

With this simple post to the XACML TC message list, it begins.

OpenAz is an effort to build a new standard open source API for authorization. The initial version of the API is based on XACML. Think of it as a standard way of interfacing with a XACML engine using Java. Now, XACML as a policy language definitely has its challenges - I dare a human being to author a meaningful policy in XACML - but the simple runtime model - a few objects - all based on attributes is pretty nice and flexible, and this is something worth building on.

I think we also have to honest and say that the existing Java standard authorization APIs - checkPermission and its JEE cousin JSR 115 - are not great general purpose authorization APIs. They are very tightly bound into the Java code level security. This is good when you're trying to protected Java applets from downloading malicious code, but presents some challenges in other contexts. On the plus side, the Java permissions API is totally standard and available - on all platforms, so you can reliably write to it - it been around for a long time.

There has been some thinking on converging the Java Permission and XACML models previously, but this is not explicitly the goal of Open Az. OpenAz ambitiously looks define a new ubiquitous standard that both PEP and PDP vendors can use to integrate against. My first foray into the OpenAz API will be on the PDP side...I'm looking to build a reference implementation of a PDP, but my true interest in this is on the PEP side. I hope that OpenAz will be the ultimate answer to Where have all the PEPs gone?

This one is definitely going to be a marathon, not a sprint, but I think that with both Oracle and Cisco making initial contributions, there is some strong industry interest which should hopefully spur adoption and consequently innovation. As always, I'm open to your suggestions, and it is open source, so feel free to get your hands dirty and help out.

Wednesday, September 2, 2009

WS-Policy and My Dog Lily


This is my dog, Lily. Besides being and adorable puppie-wuppie, she was born blind. Yet here is a picture of her swimming in a lake. I wish I had video of her...she will swim out and fetch the ball. I'm not kidding. She is amazing. So how does she do it? Well, as it turns out "sighted" dogs have lousy sight. Dogs actually have a really good sense of smell, and hearing, and Lily uses some combination of these find the ball.

WS-Policy, despite what people make think, does not necessarily make interoperability of web-services any easier. Practical interoperability is actually achieved at the WS-Security level - through the exchange of messages. WS-Policy as a standard does not prescribe what the corresponding message looks like. It just says "this message is going to be encrypted with Basic 256". We can all agree that there are lots of ways that SOAP message could look...WS-Security gives us a lot of help here, but as you wade through the various pieces of WS-Security specification, and get into things like Derived and Encrypted Keys, there are a lot of inferences that are left to be made between the WS-Policy and the SOAP message.

I'm not on a crusade against WS-Policy, but I've run into a number of customers in the past few weeks that have gotten hung up on WS-Policy and in particular OSB's inability in the current release to consume WS-Policy on a WSDL. This is just a "Blind Dog"...OSB has rich WS-Security capabilities and can work with many of those end points even if it doesn't understand the assertions. Why? Because OSB supports WS-Security 1.0, SAML 1.1, Transport Level Security with SSL...and these capabilities are broadly interoperable with a number of Web Service vendors and implementations.

The key is that OSB, and WLS and OWSM for that matter, all have the ability to define a policy to be used on the client. It does not have to come from the WS-Policy attached to the WSDL. The "trick" is that you may have to simply remove the offending WS-Policy statements from the WSDL - and save it locally - to get client side stubs to get design time tooling - OSB pipeline or JAX-WS/RPC client stubs.

This does require some understanding of what the server's WS-Policy is trying to say...that is what does it expect....version of WS-Security, Is it signed, Is it encrypted, what tokens are included? Fortunately, WLS, OSB and OWSM all include pre-built client side policies that include some best practices and common scenarios, so that in most cases, you won't have to start from scratch, or modify the client policies at all. You just need to know which one to pick...pretty straight forward, assuming that you know something about the WS-Policy and what it means. If your expectation is that WS-Policy will just magically make security happen, then I think that we as an industry are a long way away from that Nirvana.

I work with many customers that have WS-Policy implementations that both "sides" understand, but still the messages don't work. There is no substitute for testing....that is vendor-to-vendor industry interoperability testing. Vendors continue to invest in this, but in the mean time, if you're going to use WS-Policy you'll need to understand how it works at some level. Remember, SSL or some other transport level security is always a reasonable choice. It meets many SOA security use cases.