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
;
16 import com
.sun
.security
.jgss
.GSSUtil
;
19 public class SpnegoLoginModule
implements LoginModule
{
20 private final static CmsLog log
= CmsLog
.getLog(SpnegoLoginModule
.class);
22 private Subject subject
;
23 private Map
<String
, Object
> sharedState
= null;
25 private GSSContext gssContext
= null;
27 @SuppressWarnings("unchecked")
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
;
36 public boolean login() throws LoginException
{
37 byte[] spnegoToken
= (byte[]) sharedState
.get(CmsAuthUtils
.SHARED_STATE_SPNEGO_TOKEN
);
38 if (spnegoToken
== null)
40 gssContext
= checkToken(spnegoToken
);
41 if (gssContext
== null)
44 // if (!sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME)) {
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);
59 // String clientName = gssContext.getSrcName().toString();
60 // String role = clientName.substring(clientName.indexOf('@') + 1);
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();
73 public boolean commit() throws LoginException
{
74 if (gssContext
== null)
78 // Class<?> gssUtilsClass = Class.forName("com.sun.security.jgss.GSSUtil");
79 // Method createSubjectMethod = gssUtilsClass.getMethod("createSubject", GSSName.class, GSSCredential.class);
81 if (gssContext
.getCredDelegState())
82 gssSubject
= (Subject
) GSSUtil
.createSubject(gssContext
.getSrcName(), gssContext
.getDelegCred());
84 gssSubject
= (Subject
) GSSUtil
.createSubject(gssContext
.getSrcName(), null);
85 subject
.getPrincipals().addAll(gssSubject
.getPrincipals());
86 subject
.getPrivateCredentials().addAll(gssSubject
.getPrivateCredentials());
88 } catch (Exception e
) {
89 throw new LoginException("Cannot commit SPNEGO " + e
);
95 public boolean abort() throws LoginException
{
96 if (gssContext
!= null) {
99 } catch (GSSException e
) {
100 if (log
.isTraceEnabled())
101 log
.warn("Could not abort", e
);
109 public boolean logout() throws LoginException
{
110 if (gssContext
!= null) {
112 gssContext
.dispose();
113 } catch (GSSException e
) {
114 if (log
.isTraceEnabled())
115 log
.warn("Could not abort", e
);
122 private GSSContext
checkToken(byte[] authToken
) {
123 GSSManager manager
= GSSManager
.getInstance();
125 GSSContext gContext
= manager
.createContext(CmsContextImpl
.getAcceptorCredentials());
127 if (gContext
== null) {
128 log
.debug("SpnegoUserRealm: failed to establish GSSContext");
130 if (gContext
.isEstablished())
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())
139 } catch (GSSException gsse
) {
140 log
.warn(gsse
, gsse
);
147 public static boolean hasAcceptorCredentials() {
148 return CmsContextImpl
.getAcceptorCredentials() != null;