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