Kumar Jayanti's Blog
Kumar Jayanti is a staff engineer at Sun Microsystems and works in the Web Technologies and Standards team. In his current role, Kumar is the implementation lead for GlassFish V3 Security, Metro WebServices Security and also the specification and implementation lead for the SAAJ (JSR 67). He has been working in the areas of application and infrastructure security effort at Sun since early 2004. Kumar holds an M.Tech degree in Computer Science from IIT Mumbai, India. His areas of interest include Distributed computing, CORBA, XML, WebServices and Security.
Attaching Security Policies to Individual Operations
Posted by kumarjayanti on July 01, 2009 at 06:36 AM | Permalink
| Comments (0)
The earliest version of WS-SecurityPolicy implemented during early days of Metro/WSIT did not allow Binding Assertions to be attached to any scope other than the EndPoint scope. The latest versions of WS-SecurityPolicy specification allows Binding Assertions to be attached to operation scope.
We had a bug in our Metro code which prevented this from working correctly all these days. With latest metro 2.0 nightly builds starting 2nd July you should be able to use this feature.
My team member suresh has nore details on it here
We have also asked our NetBeans Plugin Expert to make this feature available via NetBeans. Until then you would have to manually place the policy references at the operation scope.
Security Token Configuration in Metro
Posted by kumarjayanti on June 01, 2009 at 04:45 AM | Permalink
| Comments (4)
In this post, i would like to describe how to configure various types of security tokens that Metro supports. There are various aspects to token configuration depending on the type of the token and the article i wrote long ago is outdated, things have changed for good and i will talk about it here.
The details in this entry would be applicable to Metro 2.0 EA (to be released for JavaOne 2009) and Metro 2.0 Final Release. I would not be at JavaOne 2009 but the Metro Architect Harold and Jiandong (Lead for WebServices Trust and SecureConversation implementation in Metro) would present a Technical Session : Metro Web Services Security Usage Scenarios on Thursday, June 04, 9:30 AM - 10:30 AM Hall E 134. So if you are attending JavaOne 2009 do plan to go for the session.
The WS-SecurityPolicy specification defines a whole set of token assertions that can be used for securing SOAP messages. Metro supports some of them. The token assertions are abstract declarations of the type of token to be used and can contain other information such as claims, reference types etc. The abstract token assertions need to be bound to concrete physical tokens from the runtime environment for Metro to be able to secure the messages. The notation for establishing this binding is not defined in any specification and hence each vendor implementation would have its own proprietary way of doing this. In this blog i would describe how the binding is done in Metro. Metro attempts to move this binding to a standard API JSR 196 CallbackHandler and Callbacks defined by the JSR. However the result is not a totally clean binding (devoid to proprietary stuff). This is because JSR 196 defines a minimal set of necessary callbacks but we endup requiring other types of callbacks. To this effect the JSR 196 specification does allow the Callback Handler to handle other types of callbacks where necessary.
Note that there is support in NetBeans for most (if not all) of the configurations described in this post. There is still scope for refining and repackaging the current Metro Security Token configuration framework but i have been spending less time on it due to my GlassFish Security engagements for the last 2 years. This post is very informal (not so well organized) and is a prelude to Documentation that would appear with Metro 2.0 Final Release. However it contains the set of all configurations (some of which were probably not publicly documented before).
Underlying Architecture for Token Configuration
Before describing the token configuration details it would help if i describe how the metro security runtime tries to obtain the configuration. As metro security involved from early days in 2004 we realized two things :
1. The use of the JAAS CallbackHandler for obtaining Tokens especially username/password is a standard approach in Java.
2. Metro has to run in different enviroments/containers and there could be different set of Callback Vocabularies in different environments. For example Pre-Metro XWSS defined its own set of Callbacks and JSR 196 defines another set of standard Callback subset in the javax package.
So it was clear that Metro Security runtime cannot depend on any specific set of Callback's if it were to run on different environments, but instead should utilize the callback vocabulary of the target container on which it is running. Accordingly the Metro Security runtime defines an Internal SPI called SecurityEnvironment which has necessary methods for retrieving Tokens of various types, possibly using some search criteria (for example locate a certificate which has a given IssuerName and IssuerSerial value). Then there are different default implementations of this SPI within metro and the right implementation is picked up based on the environment. The SPI implementation would then invoke the container/environment specific callbackhandler. So one can expect that the configuration required by metro would be influenced to some extent by the configuration needed by the underlying CallbackHandler used by the container (although the general design goal is to make the configuration agnostic to the underlying CallbackHandler of the target container).
In this post you would see the use of term CallbackHandler and Validator at several places and the way these pieces fit together is that metro has two default implementation's of the SecurityEnvironment SPI, one implementation used for all Non-GlassFish containers and also for GlassFish Non-109 deployments and another implementation of the SPI for GlassFish 109 deployments. This is because 109 deployments on GlassFish can levarage the Default JSR 196 CallbackHandler implemented by GlassFish. Using a native CallbackHandler supported by the container results in less configuration required in the Metro configuration file(s), although it may put some external (container specific) configuration requirements.
So the first implementation of the SPI invokes a Metro DefaultCallbackHandler (which operates on the Metro/XWSS specific Callback vocabulary) and the second implementation invokes the JSR 196 CallbackHandler of GlassFish. So the DefaultCallbackHandler in the first case is a Gigantic Wrapper which would inturn delegate to any CallbackHandler(s) and Validator(s) specified in by the developer in the Metro configuration files. In the second case it turns out that the JSR 196 Callback vocabular is actually a subset of what would be required in a WS-Security environment and hence the SecurityEnviroment SPI uses a Mixed approach. If a JSR 196 Callback exists for a particular case it would invoke the JSR 196 CallbackHandler by default unless overriden by a metro specific configuration. If a JSR 196 Callback does not exist (or was overriden) for a task then it would directly invoke any CallbackHandler(s) and Validator(s) specified by the developer in the Metro configuration.
Note: It is possible for GlassFish Non-109 (plain-jaxws) webservice deployments to make use of the JSR 196 dependent SecurityEnvironment SPI implementation. This can be achieved by placing the jar gf-196-hook.jar in the lib directory of GlassFish and re-starting GlassFish.
Metro Security supports the following token assertions defined in the WS-SecurityPolicy specfication :
- Timestamp Token
- Username Token
- X509Token
- SAML Token
- Kerberos Token
- Issued Token
- SecureConversation Token
The last one is not an authentication token but metro allows certain configuration for it and hence i have mentioned it there.
Let us look at the token configuration details for various tokens supported by Metro. We would also refer to them as Configuration Assertions in this post since they are really proprietary assertion's using the same WS-Policy syntax. One might wonder if it could cause some interoperability problems but the fact of matter is that these assertions are required to bind the various aspects of the Token Assertions to phyiscal entities, and these assertions are marked with Visibility attribute private stating that the other party importing the WSDL would not see these assertion.
Continue Reading...
Overriding WebServiceContext in Metro to handle security related methods
Posted by kumarjayanti on May 26, 2009 at 02:25 AM | Permalink
| Comments (0)
One of the design goals of Metro is to be able to run on any Application Server as a WebServices Stack. One project that i know levarages this ability is OpenSSO. The OpenSSO product is supported on several application servers.
There are two methods in the JAXWS defined WebServiceContext interface which relate to the Caller Identity (getUserPrincipal()) and Role Membership (isUserInRole()) of the caller respectively. These methods cannot be implemented in a generic manner. This is because the container's representation of the caller principal differs between different application servers. If nothing else the Java Principal class itself would be a container specific one.
When JSR 196 is enabled in Metro then it actually provides an opportunity to populate the containers representation of the caller principal. This is because Metro would invoke the JSR 196 defined CallerPrincipalCallback. However most usages of Metro on other containers has been without using JSR 196 underneath. So there is a need to override the method getUserPrincipal() on the WebServiceContext for the target container.
The other method which allows users to do programmatic access control is isUserInRole. Java EE specs do not enumerate how principals are to be mapped to roles for the simple reason that there is no unique way of doing this. Different application server's provide different ways of managing the principal to role mapping and there is no standard Java EE API to query the RoleMapping information, add to this the fact that Metro needs to work on Non JavaEE compliant containers such as Tomcat. So the method isUserInRole() on the WebServiceContext again needs to be overriden for the target container.
With latest Metro 2.0 builds you can thus override the default WebServiceContext implementation with a custom one. The class should implement com.sun.xml.ws.api.server.WebServiceContextDelegate The implementing class should have a Constructor which accepts a delegate of type com.sun.xml.ws.api.server.WebServiceContextDelegate. Note that when Metro is running on GlassFish container there is no need to override WebServiceContext implementation for JSR 109 webservices.
Here is a sample, where i ovverride only the getUserPrincipal(). The idea is that one can delegate the implementation of all the other methods on this interface to the default implementation which is passed as a constructor argument and only handle the two security related methods in a container specific way.
import com.sun.xml.ws.api.message.Packet;
import com.sun.xml.ws.api.server.WSEndpoint;
import java.security.Principal;
import java.util.Set;
import javax.security.auth.Subject;
public class WebServiceContextDelegate implements com.sun.xml.ws.api.server.WebServiceContextDelegate {
private static final String AUTH_SUBJECT="javax.security.auth.Subject";
private com.sun.xml.ws.api.server.WebServiceContextDelegate delegate = null;
public WebServiceContextDelegate(com.sun.xml.ws.api.server.WebServiceContextDelegate delegate) {
this.delegate = delegate;
}
public Principal getUserPrincipal(Packet packet) {
Subject subject = (Subject)packet.invocationProperties.get(AUTH_SUBJECT);
if (subject == null) {
return null;
}
Set set = subject.getPrincipals(Principal.class);
if (set.isEmpty()) { return null; }
return set.iterator().next();
}
public boolean isUserInRole(Packet arg0, String arg1) {
//TODO: implement isUserInRole as appropriate for the server
return false;
}
public String getEPRAddress(Packet arg0, WSEndpoint arg1) {
return delegate.getEPRAddress(arg0, arg1);
}
public String getWSDLAddress(Packet arg0, WSEndpoint arg1) {
return delegate.getWSDLAddress(arg0, arg1);
}
}
The last step is to configure this WebServiceContext class name. This can be done on a per-application basis by specifying the following META-INF/services entry inside your application WAR. META-INF/services/com.sun.xml.ws.api.server.WebServiceContextDelegate The content of the file com.sun.xml.ws.api.server.WebServiceContextDelegate should be the fully qualified classname of your implementation class. And lastly it is expected that the implementation class is available inside WEB-INF/classes of your application WAR.
If you are interested in knowing how JSR 196 can be enabled on non GlassFish containers send me a message. Metro has a pluggable security architecture where you can override the default JSR 196 AuthConfigProvider with one of your own. I will probably try to write about it some other day.
SOAP Message Security with Password Derived Keys
Posted by kumarjayanti on April 06, 2009 at 06:02 AM | Permalink
| Comments (3)
With Latest Metro 2.0 bits you can now try signing and encrypting SOAP Messages using the WSS 1.1 Password Derived Keys Feature. This is useful incase one does not want to use Certificates or Kerberos tokens etc. A secret key derived from your password would be used to sign and encrypt the SOAP messages.
Configuring Password Derived Keys can be done Via WS-SecurityPolicy assertions in the WSDL. NetBeans support for this is not yet there but one can add the assertions manually to do this.
While our QE is still testing this feature which is going to be part of Metro 2.0 release, you can already start using it.
Checkout the post by my team member suresh for more info on this feature :
Post By Suresh
Metro 2.0 Nightlies can be obtained here:
Metro 2.0 Nightlies
 |