JBossWS CXF, Kerberos and wsse
zenor Apr 30, 2014 8:52 AMHallo all.
I need to use both UsernameToken and KerberosToken to authenticate webservices running on JBoss AS 7.1 / 7.2.
As found in many documentations, I added the @Policy annotation to reference to the required wsp policies, as you can see:
@WebService(name = "SecurityService", targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wssecuritypolicy")
@Policy(uri = "policy/ws-security.xml", placement = Policy.Placement.BINDING)
public interface ServiceIface {
@WebMethod()
public String sayHello(String String);
}
In the implementation, I registered the KerberosTokenValidator:
@WebService( //
portName = "SecurityServicePort", //
serviceName = "SecurityService", //
targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wssecuritypolicy" //
)
@EndpointProperties(value = { //
@EndpointProperty(key = "ws-security.validate.token", value = "false"), //
@EndpointProperty(key = "ws-security.bst.validator", value = "org.apache.ws.security.validate.KerberosTokenValidator") //
})
public class ServiceImpl implements ServiceIface {
@Resource
private WebServiceContext wsContext;
@WebMethod()
public String sayHello(String string) {
String info = "Hello <" + string + ">";
Principal principal = wsContext.getUserPrincipal();
if (principal != null) {
info += " (" + principal.getName() + ", " + principal.getClass().getName() + ")";
}
return info;
}
}
The referenced policies file looks like the following:
<?xml version="1.0" encoding="UTF-8"?> <wsp:Policy xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <wsp:ExactlyOne> <wsp:Policy> <sp:KerberosToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <!-- <sp:WssKerberosV5ApReqToken11 /> --> <sp:WssGssKerberosV5ApReqToken11 /> </wsp:Policy> </sp:KerberosToken> </wsp:Policy> <wsp:Policy> <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <sp:WssUsernameToken11 /> </wsp:Policy> </sp:UsernameToken> </wsp:Policy> </wsp:ExactlyOne> </wsp:Policy>
Obviously, I configured the security-domain in JBoss standalone.xml:
<security-domain name="com.sun.security.jgss.accept" cache-type="default"> <authentication> <login-module code="com.sun.security.auth.module.Krb5LoginModule" flag="required"> <module-option name="debug" value="true"/> <module-option name="doNotPrompt" value="true"/> <module-option name="storeKey" value="true"/> <module-option name="useKeyTab" value="true"/> <module-option name="realm" value="PROV.BZ"/> <module-option name="principal" value="ceesvc"/> </login-module> </authentication> </security-domain>
The first problem I have found, using a KerberosToken, is that the @SecurityDomain annotation was ignored so the KerberosTokenValidator.getContextName() method returns a null value.
Same result if I configure the security domain through jboss-web.xml (used correctly by UsernameToken instead):
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.4//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_4_0.dtd"> <jboss-web> <security-domain>java:/jaas/com.sun.security.jgss.accept</security-domain> </jboss-web>
This is the exception:
Caused by: org.apache.ws.security.WSSecurityException: General security error (An error occurred in trying to obtain a TGT: Invalid null input: name)
at org.apache.ws.security.validate.KerberosTokenValidator.validate(KerberosTokenValidator.java:175) [wss4j-1.6.9.jar:1.6.9]
at org.apache.ws.security.processor.BinarySecurityTokenProcessor.handleToken(BinarySecurityTokenProcessor.java:91) [wss4j-1.6.9.jar:1.6.9]
So I writed a custom KerberosTokenValidator that overload getContextName() method and return a correct security domain.
The second problem is that I see two different results depends on which profile will be used:
using an UsernameToken I obtain correctly:
- Principal: ex1330@DOMAIN (which is my kerberos account)
- Subject: ex1330@DOMAIN
using a KerberosToken the result is:
- Principal: ex1330@DOMAIN (which is my kerberos account)
- Subject: ceesvc@DOMAIN (which is the account used to run JBoss windows service)
Someone can explain me if some configuration is missing or if there's a different way to use kerberos authentication through wsse?
Thanks in advance.