1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.common.kerberos;
21
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.security.Key;
25 import java.security.Principal;
26 import java.security.PrivilegedExceptionAction;
27
28 import org.apache.wss4j.common.ext.WSSecurityException;
29 import org.apache.wss4j.common.ext.WSSecurityException.ErrorCode;
30 import org.ietf.jgss.GSSContext;
31 import org.ietf.jgss.GSSCredential;
32 import org.ietf.jgss.GSSException;
33 import org.ietf.jgss.GSSManager;
34 import org.ietf.jgss.GSSName;
35 import org.ietf.jgss.Oid;
36
37
38
39
40
41 public class KerberosClientExceptionAction implements PrivilegedExceptionAction<KerberosContext> {
42 private static final boolean IS_IBM_VENDOR = System.getProperty("java.vendor").startsWith("IBM");
43
44 private static final String SUN_JGSS_INQUIRE_TYPE_CLASS = "com.sun.security.jgss.InquireType";
45 private static final String SUN_JGSS_EXT_GSSCTX_CLASS = "com.sun.security.jgss.ExtendedGSSContext";
46
47 private static final String IBM_JGSS_INQUIRE_TYPE_CLASS = "com.ibm.security.jgss.InquireType";
48 private static final String IBM_JGSS_EXT_GSSCTX_CLASS = "com.ibm.security.jgss.ExtendedGSSContext";
49
50 private static final String JGSS_KERBEROS_TICKET_OID = "1.2.840.113554.1.2.2";
51 private static final String JGSS_SPNEGO_TICKET_OID = "1.3.6.1.5.5.2";
52
53 private Principal clientPrincipal;
54 private String serviceName;
55 private boolean isUsernameServiceNameForm;
56 private boolean requestCredDeleg;
57 private GSSCredential delegatedCredential;
58 private boolean spnego;
59 private boolean mutualAuth;
60
61 public KerberosClientExceptionAction(Principal clientPrincipal, String serviceName,
62 boolean isUsernameServiceNameForm, boolean requestCredDeleg) {
63 this(clientPrincipal, serviceName, isUsernameServiceNameForm,
64 requestCredDeleg, null, false, false);
65 }
66
67 public KerberosClientExceptionAction(Principal clientPrincipal, String serviceName,
68 boolean isUsernameServiceNameForm, boolean requestCredDeleg,
69 GSSCredential delegatedCredential,
70 boolean spnego, boolean mutualAuth) {
71 this.clientPrincipal = clientPrincipal;
72 this.serviceName = serviceName;
73 this.isUsernameServiceNameForm = isUsernameServiceNameForm;
74 this.requestCredDeleg = requestCredDeleg;
75 this.delegatedCredential = delegatedCredential;
76 this.spnego = spnego;
77 this.mutualAuth = mutualAuth;
78 }
79
80 public KerberosContext run() throws GSSException, WSSecurityException {
81 GSSManager gssManager = GSSManager.getInstance();
82
83 GSSName gssService = gssManager.createName(serviceName, isUsernameServiceNameForm
84 ? GSSName.NT_USER_NAME : GSSName.NT_HOSTBASED_SERVICE);
85 Oid oid = null;
86 GSSCredential credentials = delegatedCredential;
87 if (spnego) {
88 oid = new Oid(JGSS_SPNEGO_TICKET_OID);
89 } else {
90 oid = new Oid(JGSS_KERBEROS_TICKET_OID);
91
92 if (credentials == null) {
93 GSSName gssClient = gssManager.createName(clientPrincipal.getName(), GSSName.NT_USER_NAME);
94 credentials =
95 gssManager.createCredential(
96 gssClient, GSSCredential.DEFAULT_LIFETIME, oid, GSSCredential.INITIATE_ONLY
97 );
98 }
99 }
100
101 GSSContext secContext =
102 gssManager.createContext(
103 gssService, oid, credentials, GSSContext.DEFAULT_LIFETIME
104 );
105
106 secContext.requestMutualAuth(mutualAuth);
107 secContext.requestCredDeleg(requestCredDeleg);
108
109 byte[] token = new byte[0];
110 byte[] returnedToken = secContext.initSecContext(token, 0, token.length);
111
112 KerberosContext krbCtx = new KerberosContext();
113 krbCtx.setGssContext(secContext);
114 krbCtx.setKerberosToken(returnedToken);
115
116 try {
117 @SuppressWarnings("rawtypes")
118 Class inquireType = Class.forName(IS_IBM_VENDOR ? IBM_JGSS_INQUIRE_TYPE_CLASS
119 : SUN_JGSS_INQUIRE_TYPE_CLASS);
120
121 @SuppressWarnings("rawtypes")
122 Class extendedGSSContext = Class.forName(IS_IBM_VENDOR ? IBM_JGSS_EXT_GSSCTX_CLASS
123 : SUN_JGSS_EXT_GSSCTX_CLASS);
124
125 @SuppressWarnings("unchecked")
126 Method inquireSecContext = extendedGSSContext.getMethod("inquireSecContext", inquireType);
127
128 @SuppressWarnings("unchecked")
129 Key key = (Key) inquireSecContext.invoke(secContext, Enum.valueOf(inquireType, "KRB5_GET_SESSION_KEY"));
130
131 krbCtx.setSecretKey(key);
132 } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
133 | InvocationTargetException e) {
134 throw new WSSecurityException(
135 ErrorCode.FAILURE, e, "kerberosServiceTicketError"
136 );
137 }
138
139 return krbCtx;
140 }
141 }