1 package org
.argeo
.cms
.auth
;
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
;
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 import org
.ietf
.jgss
.GSSName
;
17 import com
.sun
.security
.jgss
.GSSUtil
;
20 public class SpnegoLoginModule
implements LoginModule
{
21 private final static CmsLog log
= CmsLog
.getLog(SpnegoLoginModule
.class);
23 private Subject subject
;
24 private Map
<String
, Object
> sharedState
= null;
26 private GSSContext gssContext
= null;
28 @SuppressWarnings("unchecked")
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
;
37 public boolean login() throws LoginException
{
38 byte[] spnegoToken
= (byte[]) sharedState
.get(CmsAuthUtils
.SHARED_STATE_SPNEGO_TOKEN
);
39 if (spnegoToken
== null)
41 gssContext
= checkToken(spnegoToken
);
42 if (gssContext
== null)
45 if (!sharedState
.containsKey(CmsAuthUtils
.SHARED_STATE_NAME
)) {
47 if (gssContext
.getCredDelegState()) {
48 // commit will succeeed only if we have credential delegation
49 GSSName name
= gssContext
.getSrcName();
50 String username
= name
.toString();
51 sharedState
.put(CmsAuthUtils
.SHARED_STATE_NAME
, username
);
53 } catch (GSSException e
) {
54 throw new IllegalStateException("Cannot retrieve SPNEGO name", e
);
62 public boolean commit() throws LoginException
{
63 if (gssContext
== null)
68 if (gssContext
.getCredDelegState())
69 gssSubject
= (Subject
) GSSUtil
.createSubject(gssContext
.getSrcName(), gssContext
.getDelegCred());
71 gssSubject
= (Subject
) GSSUtil
.createSubject(gssContext
.getSrcName(), null);
72 // without credential delegation we won't have access to the Kerberos key
73 subject
.getPrincipals().addAll(gssSubject
.getPrincipals());
74 subject
.getPrivateCredentials().addAll(gssSubject
.getPrivateCredentials());
76 } catch (Exception e
) {
77 throw new LoginException("Cannot commit SPNEGO " + e
);
83 public boolean abort() throws LoginException
{
84 if (gssContext
!= null) {
87 } catch (GSSException e
) {
88 if (log
.isTraceEnabled())
89 log
.warn("Could not abort", e
);
97 public boolean logout() throws LoginException
{
98 if (gssContext
!= null) {
100 gssContext
.dispose();
101 } catch (GSSException e
) {
102 if (log
.isTraceEnabled())
103 log
.warn("Could not abort", e
);
110 private GSSContext
checkToken(byte[] authToken
) {
111 GSSManager manager
= GSSManager
.getInstance();
113 GSSContext gContext
= manager
.createContext(CmsContextImpl
.getCmsContext().getAcceptorCredentials());
114 if (gContext
== null) {
115 log
.debug("SpnegoUserRealm: failed to establish GSSContext");
117 if (gContext
.isEstablished())
119 byte[] outToken
= gContext
.acceptSecContext(authToken
, 0, authToken
.length
);
120 if (outToken
!= null)
121 sharedState
.put(CmsAuthUtils
.SHARED_STATE_SPNEGO_OUT_TOKEN
, outToken
);
122 if (gContext
.isEstablished())
126 } catch (GSSException gsse
) {
127 log
.warn(gsse
, gsse
);