]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/auth/SpnegoLoginModule.java
Fix automated Kerberos config
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / auth / SpnegoLoginModule.java
1 package org.argeo.cms.auth;
2
3 import java.lang.reflect.Method;
4 import java.util.Map;
5
6 import javax.security.auth.Subject;
7 import javax.security.auth.callback.CallbackHandler;
8 import javax.security.auth.login.LoginException;
9 import javax.security.auth.spi.LoginModule;
10
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13 import org.argeo.cms.internal.kernel.Activator;
14 import org.ietf.jgss.GSSContext;
15 import org.ietf.jgss.GSSCredential;
16 import org.ietf.jgss.GSSException;
17 import org.ietf.jgss.GSSManager;
18 import org.ietf.jgss.GSSName;
19
20 /** SPNEGO login */
21 public class SpnegoLoginModule implements LoginModule {
22 private final static Log log = LogFactory.getLog(SpnegoLoginModule.class);
23
24 private Subject subject;
25 private Map<String, Object> sharedState = null;
26
27 private GSSContext gssContext = null;
28
29 @SuppressWarnings("unchecked")
30 @Override
31 public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
32 Map<String, ?> options) {
33 this.subject = subject;
34 this.sharedState = (Map<String, Object>) sharedState;
35 }
36
37 @Override
38 public boolean login() throws LoginException {
39 byte[] spnegoToken = (byte[]) sharedState.get(CmsAuthUtils.SHARED_STATE_SPNEGO_TOKEN);
40 if (spnegoToken == null)
41 return false;
42 gssContext = checkToken(spnegoToken);
43 if (gssContext == null)
44 return false;
45 else
46 return true;
47 // try {
48 // String clientName = gssContext.getSrcName().toString();
49 // String role = clientName.substring(clientName.indexOf('@') + 1);
50 //
51 // log.debug("SpnegoUserRealm: established a security context");
52 // log.debug("Client Principal is: " + gssContext.getSrcName());
53 // log.debug("Server Principal is: " + gssContext.getTargName());
54 // log.debug("Client Default Role: " + role);
55 // } catch (GSSException e) {
56 // // TODO Auto-generated catch block
57 // e.printStackTrace();
58 // }
59 }
60
61 @Override
62 public boolean commit() throws LoginException {
63 if (gssContext == null)
64 return false;
65
66 try {
67 Class<?> gssUtilsClass = Class.forName("com.sun.security.jgss.GSSUtil");
68 Method createSubjectMethod = gssUtilsClass.getMethod("createSubject", GSSName.class, GSSCredential.class);
69 Subject gssSubject;
70 if (gssContext.getCredDelegState())
71 gssSubject = (Subject) createSubjectMethod.invoke(null, gssContext.getSrcName(),
72 gssContext.getDelegCred());
73 else
74 gssSubject = (Subject) createSubjectMethod.invoke(null, gssContext.getSrcName(), null);
75 subject.getPrincipals().addAll(gssSubject.getPrincipals());
76 subject.getPrivateCredentials().addAll(gssSubject.getPrivateCredentials());
77 return true;
78 } catch (Exception e) {
79 throw new LoginException("Cannot commit SPNEGO " + e);
80 }
81
82 }
83
84 @Override
85 public boolean abort() throws LoginException {
86 if (gssContext != null) {
87 try {
88 gssContext.dispose();
89 } catch (GSSException e) {
90 if (log.isTraceEnabled())
91 log.warn("Could not abort", e);
92 }
93 gssContext = null;
94 }
95 return true;
96 }
97
98 @Override
99 public boolean logout() throws LoginException {
100 if (gssContext != null) {
101 try {
102 gssContext.dispose();
103 } catch (GSSException e) {
104 if (log.isTraceEnabled())
105 log.warn("Could not abort", e);
106 }
107 gssContext = null;
108 }
109 return true;
110 }
111
112 private GSSContext checkToken(byte[] authToken) {
113 GSSManager manager = GSSManager.getInstance();
114 try {
115 GSSContext gContext = manager.createContext(Activator.getAcceptorCredentials());
116
117 if (gContext == null) {
118 log.debug("SpnegoUserRealm: failed to establish GSSContext");
119 } else {
120 if (gContext.isEstablished())
121 return gContext;
122 byte[] outToken = gContext.acceptSecContext(authToken, 0, authToken.length);
123 if (outToken != null)
124 sharedState.put(CmsAuthUtils.SHARED_STATE_SPNEGO_OUT_TOKEN, outToken);
125 if (gContext.isEstablished())
126 return gContext;
127 }
128
129 } catch (GSSException gsse) {
130 log.warn(gsse, gsse);
131 }
132 return null;
133
134 }
135 }