blob: 3a88939b7a3b39cfd12ebaaf9d3b341996c5b240 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.wss4j.common.kerberos;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Key;
import java.security.Principal;
import java.security.PrivilegedExceptionAction;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.ext.WSSecurityException.ErrorCode;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;
/**
* This class represents a PrivilegedExceptionAction implementation to obtain a service ticket from a Kerberos
* Key Distribution Center.
*/
public class KerberosClientExceptionAction implements PrivilegedExceptionAction<KerberosContext> {
private static final boolean IS_IBM_VENDOR = System.getProperty("java.vendor").startsWith("IBM");
private static final String SUN_JGSS_INQUIRE_TYPE_CLASS = "com.sun.security.jgss.InquireType";
private static final String SUN_JGSS_EXT_GSSCTX_CLASS = "com.sun.security.jgss.ExtendedGSSContext";
private static final String IBM_JGSS_INQUIRE_TYPE_CLASS = "com.ibm.security.jgss.InquireType";
private static final String IBM_JGSS_EXT_GSSCTX_CLASS = "com.ibm.security.jgss.ExtendedGSSContext";
private static final String JGSS_KERBEROS_TICKET_OID = "1.2.840.113554.1.2.2";
private static final String JGSS_SPNEGO_TICKET_OID = "1.3.6.1.5.5.2";
private Principal clientPrincipal;
private String serviceName;
private boolean isUsernameServiceNameForm;
private boolean requestCredDeleg;
private GSSCredential delegatedCredential;
private boolean spnego;
private boolean mutualAuth;
public KerberosClientExceptionAction(Principal clientPrincipal, String serviceName,
boolean isUsernameServiceNameForm, boolean requestCredDeleg) {
this(clientPrincipal, serviceName, isUsernameServiceNameForm,
requestCredDeleg, null, false, false);
}
public KerberosClientExceptionAction(Principal clientPrincipal, String serviceName,
boolean isUsernameServiceNameForm, boolean requestCredDeleg,
GSSCredential delegatedCredential,
boolean spnego, boolean mutualAuth) {
this.clientPrincipal = clientPrincipal;
this.serviceName = serviceName;
this.isUsernameServiceNameForm = isUsernameServiceNameForm;
this.requestCredDeleg = requestCredDeleg;
this.delegatedCredential = delegatedCredential;
this.spnego = spnego;
this.mutualAuth = mutualAuth;
}
public KerberosContext run() throws GSSException, WSSecurityException {
GSSManager gssManager = GSSManager.getInstance();
GSSName gssService = gssManager.createName(serviceName, isUsernameServiceNameForm
? GSSName.NT_USER_NAME : GSSName.NT_HOSTBASED_SERVICE);
Oid oid = null;
GSSCredential credentials = delegatedCredential;
if (spnego) {
oid = new Oid(JGSS_SPNEGO_TICKET_OID);
} else {
oid = new Oid(JGSS_KERBEROS_TICKET_OID);
if (credentials == null) {
GSSName gssClient = gssManager.createName(clientPrincipal.getName(), GSSName.NT_USER_NAME);
credentials =
gssManager.createCredential(
gssClient, GSSCredential.DEFAULT_LIFETIME, oid, GSSCredential.INITIATE_ONLY
);
}
}
GSSContext secContext =
gssManager.createContext(
gssService, oid, credentials, GSSContext.DEFAULT_LIFETIME
);
secContext.requestMutualAuth(mutualAuth);
secContext.requestCredDeleg(requestCredDeleg);
byte[] token = new byte[0];
byte[] returnedToken = secContext.initSecContext(token, 0, token.length);
KerberosContext krbCtx = new KerberosContext();
krbCtx.setGssContext(secContext);
krbCtx.setKerberosToken(returnedToken);
try {
@SuppressWarnings("rawtypes")
Class inquireType = Class.forName(IS_IBM_VENDOR ? IBM_JGSS_INQUIRE_TYPE_CLASS
: SUN_JGSS_INQUIRE_TYPE_CLASS);
@SuppressWarnings("rawtypes")
Class extendedGSSContext = Class.forName(IS_IBM_VENDOR ? IBM_JGSS_EXT_GSSCTX_CLASS
: SUN_JGSS_EXT_GSSCTX_CLASS);
@SuppressWarnings("unchecked")
Method inquireSecContext = extendedGSSContext.getMethod("inquireSecContext", inquireType);
@SuppressWarnings("unchecked")
Key key = (Key) inquireSecContext.invoke(secContext, Enum.valueOf(inquireType, "KRB5_GET_SESSION_KEY"));
krbCtx.setSecretKey(key);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
| InvocationTargetException e) {
throw new WSSecurityException(
ErrorCode.FAILURE, e, "kerberosServiceTicketError"
);
}
return krbCtx;
}
}