]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/auth/SpnegoLoginModule.java
Change files path
[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 public class SpnegoLoginModule implements LoginModule {
21 private final static Log log = LogFactory.getLog(SpnegoLoginModule.class);
22
23 private Subject subject;
24 private Map<String, Object> sharedState = null;
25
26 private GSSContext gssContext = null;
27
28 @SuppressWarnings("unchecked")
29 @Override
30 public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
31 Map<String, ?> options) {
32 this.subject = subject;
33 this.sharedState = (Map<String, Object>) sharedState;
34 }
35
36 @Override
37 public boolean login() throws LoginException {
38 byte[] spnegoToken = (byte[]) sharedState.get(CmsAuthUtils.SHARED_STATE_SPNEGO_TOKEN);
39 if (spnegoToken == null)
40 return false;
41 gssContext = checkToken(spnegoToken);
42 if (gssContext == null)
43 return false;
44 try {
45 String clientName = gssContext.getSrcName().toString();
46 String role = clientName.substring(clientName.indexOf('@') + 1);
47
48 log.debug("SpnegoUserRealm: established a security context");
49 log.debug("Client Principal is: " + gssContext.getSrcName());
50 log.debug("Server Principal is: " + gssContext.getTargName());
51 log.debug("Client Default Role: " + role);
52 } catch (GSSException e) {
53 // TODO Auto-generated catch block
54 e.printStackTrace();
55 }
56
57 // TODO log in
58
59 return false;
60 }
61
62 @Override
63 public boolean commit() throws LoginException {
64 if (gssContext == null)
65 return false;
66
67 try {
68 Class<?> gssUtilsClass = Class.forName("com.sun.security.jgss.GSSUtil");
69 Method createSubjectMethod = gssUtilsClass.getMethod("createSubject", GSSName.class, GSSCredential.class);
70 Subject gssSubject = (Subject) createSubjectMethod.invoke(null, gssContext.getSrcName(),
71 gssContext.getDelegCred());
72 subject.getPrincipals().addAll(gssSubject.getPrincipals());
73 subject.getPrivateCredentials().addAll(gssSubject.getPrivateCredentials());
74 return true;
75 } catch (Exception e) {
76 // TODO Auto-generated catch block
77 e.printStackTrace();
78 return false;
79 }
80
81 }
82
83 @Override
84 public boolean abort() throws LoginException {
85 // TODO Auto-generated method stub
86 return false;
87 }
88
89 @Override
90 public boolean logout() throws LoginException {
91 // TODO Auto-generated method stub
92 return false;
93 }
94
95 private GSSContext checkToken(byte[] authToken) {
96 GSSManager manager = GSSManager.getInstance();
97 try {
98 GSSContext gContext = manager.createContext(Activator.getAcceptorCredentials());
99
100 if (gContext == null) {
101 log.debug("SpnegoUserRealm: failed to establish GSSContext");
102 } else {
103 if (gContext.isEstablished())
104 return gContext;
105 byte[] outToken = gContext.acceptSecContext(authToken, 0, authToken.length);
106 if (outToken != null)
107 sharedState.put(CmsAuthUtils.SHARED_STATE_SPNEGO_OUT_TOKEN, outToken);
108 if (gContext.isEstablished())
109 return gContext;
110 }
111
112 } catch (GSSException gsse) {
113 log.warn(gsse, gsse);
114 }
115 return null;
116
117 }
118 }