1 package org
.argeo
.cms
.auth
;
3 import java
.lang
.reflect
.Method
;
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
;
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
;
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)
47 // String clientName = gssContext.getSrcName().toString();
48 // String role = clientName.substring(clientName.indexOf('@') + 1);
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();
61 public boolean commit() throws LoginException
{
62 if (gssContext
== null)
66 Class
<?
> gssUtilsClass
= Class
.forName("com.sun.security.jgss.GSSUtil");
67 Method createSubjectMethod
= gssUtilsClass
.getMethod("createSubject", GSSName
.class, GSSCredential
.class);
69 if (gssContext
.getCredDelegState())
70 gssSubject
= (Subject
) createSubjectMethod
.invoke(null, gssContext
.getSrcName(),
71 gssContext
.getDelegCred());
73 gssSubject
= (Subject
) createSubjectMethod
.invoke(null, gssContext
.getSrcName(), null);
74 subject
.getPrincipals().addAll(gssSubject
.getPrincipals());
75 subject
.getPrivateCredentials().addAll(gssSubject
.getPrivateCredentials());
77 } catch (Exception e
) {
78 throw new LoginException("Cannot commit SPNEGO " + e
);
84 public boolean abort() throws LoginException
{
85 if (gssContext
!= null) {
88 } catch (GSSException e
) {
89 if (log
.isTraceEnabled())
90 log
.warn("Could not abort", e
);
98 public boolean logout() throws LoginException
{
99 if (gssContext
!= null) {
101 gssContext
.dispose();
102 } catch (GSSException e
) {
103 if (log
.isTraceEnabled())
104 log
.warn("Could not abort", e
);
111 private GSSContext
checkToken(byte[] authToken
) {
112 GSSManager manager
= GSSManager
.getInstance();
114 GSSContext gContext
= manager
.createContext(CmsContextImpl
.getAcceptorCredentials());
116 if (gContext
== null) {
117 log
.debug("SpnegoUserRealm: failed to establish GSSContext");
119 if (gContext
.isEstablished())
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())
128 } catch (GSSException gsse
) {
129 log
.warn(gsse
, gsse
);
136 public static boolean hasAcceptorCredentials() {
137 return CmsContextImpl
.getAcceptorCredentials() != null;