]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/auth/SpnegoLoginModule.java
Use runtime namespace context as default.
[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.argeo.api.cms.CmsLog;
12 import org.argeo.cms.internal.runtime.CmsContextImpl;
13 import org.ietf.jgss.GSSContext;
14 import org.ietf.jgss.GSSCredential;
15 import org.ietf.jgss.GSSException;
16 import org.ietf.jgss.GSSManager;
17 import org.ietf.jgss.GSSName;
18
19 /** SPNEGO login */
20 public class SpnegoLoginModule implements LoginModule {
21 private final static CmsLog log = CmsLog.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 else
45 return true;
46 // try {
47 // String clientName = gssContext.getSrcName().toString();
48 // String role = clientName.substring(clientName.indexOf('@') + 1);
49 //
50 // log.debug("SpnegoUserRealm: established a security context");
51 // log.debug("Client Principal is: " + gssContext.getSrcName());
52 // log.debug("Server Principal is: " + gssContext.getTargName());
53 // log.debug("Client Default Role: " + role);
54 // } catch (GSSException e) {
55 // // TODO Auto-generated catch block
56 // e.printStackTrace();
57 // }
58 }
59
60 @Override
61 public boolean commit() throws LoginException {
62 if (gssContext == null)
63 return false;
64
65 try {
66 Class<?> gssUtilsClass = Class.forName("com.sun.security.jgss.GSSUtil");
67 Method createSubjectMethod = gssUtilsClass.getMethod("createSubject", GSSName.class, GSSCredential.class);
68 Subject gssSubject;
69 if (gssContext.getCredDelegState())
70 gssSubject = (Subject) createSubjectMethod.invoke(null, gssContext.getSrcName(),
71 gssContext.getDelegCred());
72 else
73 gssSubject = (Subject) createSubjectMethod.invoke(null, gssContext.getSrcName(), null);
74 subject.getPrincipals().addAll(gssSubject.getPrincipals());
75 subject.getPrivateCredentials().addAll(gssSubject.getPrivateCredentials());
76 return true;
77 } catch (Exception e) {
78 throw new LoginException("Cannot commit SPNEGO " + e);
79 }
80
81 }
82
83 @Override
84 public boolean abort() throws LoginException {
85 if (gssContext != null) {
86 try {
87 gssContext.dispose();
88 } catch (GSSException e) {
89 if (log.isTraceEnabled())
90 log.warn("Could not abort", e);
91 }
92 gssContext = null;
93 }
94 return true;
95 }
96
97 @Override
98 public boolean logout() throws LoginException {
99 if (gssContext != null) {
100 try {
101 gssContext.dispose();
102 } catch (GSSException e) {
103 if (log.isTraceEnabled())
104 log.warn("Could not abort", e);
105 }
106 gssContext = null;
107 }
108 return true;
109 }
110
111 private GSSContext checkToken(byte[] authToken) {
112 GSSManager manager = GSSManager.getInstance();
113 try {
114 GSSContext gContext = manager.createContext(CmsContextImpl.getAcceptorCredentials());
115
116 if (gContext == null) {
117 log.debug("SpnegoUserRealm: failed to establish GSSContext");
118 } else {
119 if (gContext.isEstablished())
120 return gContext;
121 byte[] outToken = gContext.acceptSecContext(authToken, 0, authToken.length);
122 if (outToken != null)
123 sharedState.put(CmsAuthUtils.SHARED_STATE_SPNEGO_OUT_TOKEN, outToken);
124 if (gContext.isEstablished())
125 return gContext;
126 }
127
128 } catch (GSSException gsse) {
129 log.warn(gsse, gsse);
130 }
131 return null;
132
133 }
134
135 @Deprecated
136 public static boolean hasAcceptorCredentials() {
137 return CmsContextImpl.getAcceptorCredentials() != null;
138 }
139 }