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.