![]() |
Fox's Pages | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
UW home
|
Updated: March 28, 2006 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
These instructions are intended for University of Washington clients connecting to C&C webservices that require client certificate authentication. The particular example is the University's ASTRA webservice.
Hopefully these instructions may also be helpful in other applications.
$ wsdl="https://ucs.admin.washington.edu/astraws/astraws.asmx?wsdl"
$ java WSDL2Java -t $wsdl
package edu.washington.admin.ucs.astra;
...
public void test1AuthzProviderSoapGetAuthz() throws Exception {
edu.washington.admin.ucs.astra.AuthzProviderSoapStub binding;
try {
binding = (edu.washington.admin.ucs.astra.AuthzProviderSoapStub)
new edu.washington.admin.ucs.astra.AuthzProviderLocator().getAuthzProviderSoap();
} catch (javax.xml.rpc.ServiceException jre) {
if(jre.getLinkedCause()!=null)
jre.getLinkedCause().printStackTrace();
throw new junit.framework.AssertionFailedError(
"JAX-RPC ServiceException caught: " + jre);
}
...
In practice we can usually get rid of the 'Stub's and just go with,
package edu.washington.admin.ucs.astra;
...
AuthzProviderSoap astra = null;
try {
astra = (AuthzProviderSoapStub) new AuthzProviderLocator().getAuthzProviderSoap();
} catch (javax.xml.rpc.ServiceException jre) {
if(jre.getLinkedCause()!=null) jre.getLinkedCause().printStackTrace();
throw new Exception("JAX-RPC ServiceException caught: " + jre);
}
...
Auth auth = new Auth();
Party party = new Party();
Role role = new Role();
Environment env = new Environment();
Privilege priv = new Privilege();
Action action = new Action();
SpanOfControl span = new SpanOfControl();
party.setUwNetid(userid);
env.setCode("eval");
priv.setCode("BulkEmail");
auth.setParty(party);
auth.setEnvironment(env);
auth.setPrivilege(priv);
auth.setRole(role);
auth.setAction(action);
auth.setSpanOfControlCollection(new SpanOfControl[]{span});
Authz az = null;
try {
az = astra.getAuthz(auth);
} catch (Exception e) {
System.err.println("Caught Exception: " + e.getMessage());
}
Auth[] aa = az.getAuthCollection();
try {
for (int i = 0; i<9; i++) {
Auth a = aa[i];
System.out.println("Role: " + a.getRole().getCode());
System.out.println("Action: " + a.getAction().getCode());
}
} catch (ArrayIndexOutOfBoundsException e) {
print something
}
If you're accessing a University of Washington service you need to accept the University's UW Services CA certificates. You could just add them to Java's default certificate store, JAVA_HOME/jre/lib/security/cacerts, but then you're accepting every fly-by-night CA in that store. Better to make a new store and put in it only those certificate you have to trust.
$ keytool -import -alias uwca -file uwca.crt \
-keystore trusted.jks
-Davax.net.ssl.trustStore=trusted.jks
University C&C servers usually use certificate authentication and require certificates issued by the University's UWCA. These are available without charge to authorized administrators of University systems.
The keys and certificates generated by standard keytool operations will work with openssl servers but will not work for MS (IIS) servers. The difference is supposedly related to SSL v1 vs. SSL v3. I suspect, however, it has something to do with the keytool utility itself. In any case keytool methods will not work.
This method does work.
$ openssl req -nodes -newkey 1024 -keyout mycrt.key -out mycrt.req
$ openssl pkcs12 -in mycrt.crt -inkey mycrt.key \
-export -out mycrt.pk12 -nodes -CAfile uwca.crt
where the uwca.crt the UWCA's root cert.
$ keytool -import -file uwca.crt -alias uwca \
-keystore mystore.jks
$ pkcs12import.sh -file mycrt.pk12 -alias mycrt \
-keystore mystore.jks
I use the same password for both the store and the certificate. Try to remember whatever you entered; "changeit" is easy to remember and everyone knows it.
There are many ways to do this. Here are a couple. Setting Java properties is the easier, but suffers from the global nature of properties. Every application in the Java VM must use the same cert and key, and only a single cert may be specified. For many applications these restrictions are not too severe.
A more flexible method uses a custom socket factory, to which you can apply different certificates for each connection.
Several choices:
Axis allows you to override its default, JSSESocketFactory, with your own. By doing so you can specify a specific certificate for each connection. An example is this UWSocketFactory, which could be activated by the Java property
org.apache.axis.components.net.SecureSocketFactory
=edu.washington.smw.UWSocketFactory
The example uses properties, edu.washington.smw.keyStore, for example, to locate a certificate, but is easily extended to find certificates based on other parameters (e,g, remote service name). Used in a Tomcat application it could find certificates based on option settings.
|
Jim Fox UW Technology Identity and Access Management University of Washington fox@washington.edu |
© 1983-2012, University of Washington