package org.argeo.cms.auth;
-import java.lang.reflect.Method;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.internal.kernel.Activator;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.internal.runtime.CmsContextImpl;
import org.ietf.jgss.GSSContext;
-import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
+import com.sun.security.jgss.GSSUtil;
+
+/** SPNEGO login */
public class SpnegoLoginModule implements LoginModule {
- private final static Log log = LogFactory.getLog(SpnegoLoginModule.class);
+ private final static CmsLog log = CmsLog.getLog(SpnegoLoginModule.class);
private Subject subject;
private Map<String, Object> sharedState = null;
gssContext = checkToken(spnegoToken);
if (gssContext == null)
return false;
- try {
- String clientName = gssContext.getSrcName().toString();
- String role = clientName.substring(clientName.indexOf('@') + 1);
-
- log.debug("SpnegoUserRealm: established a security context");
- log.debug("Client Principal is: " + gssContext.getSrcName());
- log.debug("Server Principal is: " + gssContext.getTargName());
- log.debug("Client Default Role: " + role);
- } catch (GSSException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ else {
+ if (!sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME)) {
+ try {
+ if (gssContext.getCredDelegState()) {
+ // commit will succeeed only if we have credential delegation
+ GSSName name = gssContext.getSrcName();
+ String username = name.toString();
+ sharedState.put(CmsAuthUtils.SHARED_STATE_NAME, username);
+ }
+ } catch (GSSException e) {
+ throw new IllegalStateException("Cannot retrieve SPNEGO name", e);
+ }
+ }
+ return true;
}
-
- // TODO log in
-
- return false;
}
@Override
return false;
try {
- Class<?> gssUtilsClass = Class.forName("com.sun.security.jgss.GSSUtil");
- Method createSubjectMethod = gssUtilsClass.getMethod("createSubject", GSSName.class, GSSCredential.class);
- Subject gssSubject = (Subject) createSubjectMethod.invoke(null, gssContext.getSrcName(),
- gssContext.getDelegCred());
+ Subject gssSubject;
+ if (gssContext.getCredDelegState())
+ gssSubject = (Subject) GSSUtil.createSubject(gssContext.getSrcName(), gssContext.getDelegCred());
+ else
+ gssSubject = (Subject) GSSUtil.createSubject(gssContext.getSrcName(), null);
+ // without credential delegation we won't have access to the Kerberos key
subject.getPrincipals().addAll(gssSubject.getPrincipals());
subject.getPrivateCredentials().addAll(gssSubject.getPrivateCredentials());
return true;
} catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- return false;
+ throw new LoginException("Cannot commit SPNEGO " + e);
}
}
@Override
public boolean abort() throws LoginException {
- // TODO Auto-generated method stub
- return false;
+ if (gssContext != null) {
+ try {
+ gssContext.dispose();
+ } catch (GSSException e) {
+ if (log.isTraceEnabled())
+ log.warn("Could not abort", e);
+ }
+ gssContext = null;
+ }
+ return true;
}
@Override
public boolean logout() throws LoginException {
- // TODO Auto-generated method stub
- return false;
+ if (gssContext != null) {
+ try {
+ gssContext.dispose();
+ } catch (GSSException e) {
+ if (log.isTraceEnabled())
+ log.warn("Could not abort", e);
+ }
+ gssContext = null;
+ }
+ return true;
}
private GSSContext checkToken(byte[] authToken) {
GSSManager manager = GSSManager.getInstance();
try {
- GSSContext gContext = manager.createContext(Activator.getAcceptorCredentials());
-
+ GSSContext gContext = manager.createContext(CmsContextImpl.getCmsContext().getAcceptorCredentials());
if (gContext == null) {
log.debug("SpnegoUserRealm: failed to establish GSSContext");
} else {
return null;
}
+
}