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
.apache
.commons
.logging
.Log
;
12 import org
.apache
.commons
.logging
.LogFactory
;
13 import org
.argeo
.cms
.internal
.kernel
.Activator
;
14 import org
.ietf
.jgss
.GSSContext
;
15 import org
.ietf
.jgss
.GSSCredential
;
16 import org
.ietf
.jgss
.GSSException
;
17 import org
.ietf
.jgss
.GSSManager
;
18 import org
.ietf
.jgss
.GSSName
;
21 public class SpnegoLoginModule
implements LoginModule
{
22 private final static Log log
= LogFactory
.getLog(SpnegoLoginModule
.class);
24 private Subject subject
;
25 private Map
<String
, Object
> sharedState
= null;
27 private GSSContext gssContext
= null;
29 @SuppressWarnings("unchecked")
31 public void initialize(Subject subject
, CallbackHandler callbackHandler
, Map
<String
, ?
> sharedState
,
32 Map
<String
, ?
> options
) {
33 this.subject
= subject
;
34 this.sharedState
= (Map
<String
, Object
>) sharedState
;
38 public boolean login() throws LoginException
{
39 byte[] spnegoToken
= (byte[]) sharedState
.get(CmsAuthUtils
.SHARED_STATE_SPNEGO_TOKEN
);
40 if (spnegoToken
== null)
42 gssContext
= checkToken(spnegoToken
);
43 if (gssContext
== null)
48 // String clientName = gssContext.getSrcName().toString();
49 // String role = clientName.substring(clientName.indexOf('@') + 1);
51 // log.debug("SpnegoUserRealm: established a security context");
52 // log.debug("Client Principal is: " + gssContext.getSrcName());
53 // log.debug("Server Principal is: " + gssContext.getTargName());
54 // log.debug("Client Default Role: " + role);
55 // } catch (GSSException e) {
56 // // TODO Auto-generated catch block
57 // e.printStackTrace();
62 public boolean commit() throws LoginException
{
63 if (gssContext
== null)
67 Class
<?
> gssUtilsClass
= Class
.forName("com.sun.security.jgss.GSSUtil");
68 Method createSubjectMethod
= gssUtilsClass
.getMethod("createSubject", GSSName
.class, GSSCredential
.class);
70 if (gssContext
.getCredDelegState())
71 gssSubject
= (Subject
) createSubjectMethod
.invoke(null, gssContext
.getSrcName(),
72 gssContext
.getDelegCred());
74 gssSubject
= (Subject
) createSubjectMethod
.invoke(null, gssContext
.getSrcName(), null);
75 subject
.getPrincipals().addAll(gssSubject
.getPrincipals());
76 subject
.getPrivateCredentials().addAll(gssSubject
.getPrivateCredentials());
78 } catch (Exception e
) {
79 throw new LoginException("Cannot commit SPNEGO " + e
);
85 public boolean abort() throws LoginException
{
86 if (gssContext
!= null) {
89 } catch (GSSException e
) {
90 if (log
.isTraceEnabled())
91 log
.warn("Could not abort", e
);
99 public boolean logout() throws LoginException
{
100 if (gssContext
!= null) {
102 gssContext
.dispose();
103 } catch (GSSException e
) {
104 if (log
.isTraceEnabled())
105 log
.warn("Could not abort", e
);
112 private GSSContext
checkToken(byte[] authToken
) {
113 GSSManager manager
= GSSManager
.getInstance();
115 GSSContext gContext
= manager
.createContext(Activator
.getAcceptorCredentials());
117 if (gContext
== null) {
118 log
.debug("SpnegoUserRealm: failed to establish GSSContext");
120 if (gContext
.isEstablished())
122 byte[] outToken
= gContext
.acceptSecContext(authToken
, 0, authToken
.length
);
123 if (outToken
!= null)
124 sharedState
.put(CmsAuthUtils
.SHARED_STATE_SPNEGO_OUT_TOKEN
, outToken
);
125 if (gContext
.isEstablished())
129 } catch (GSSException gsse
) {
130 log
.warn(gsse
, gsse
);