View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.security;
20  
21  import java.util.Properties;
22  
23  import javax.security.auth.Subject;
24  import javax.servlet.ServletRequest;
25  
26  import org.eclipse.jetty.server.UserIdentity;
27  import org.eclipse.jetty.util.B64Code;
28  import org.eclipse.jetty.util.component.AbstractLifeCycle;
29  import org.eclipse.jetty.util.log.Log;
30  import org.eclipse.jetty.util.log.Logger;
31  import org.eclipse.jetty.util.resource.Resource;
32  import org.ietf.jgss.GSSContext;
33  import org.ietf.jgss.GSSCredential;
34  import org.ietf.jgss.GSSException;
35  import org.ietf.jgss.GSSManager;
36  import org.ietf.jgss.GSSName;
37  import org.ietf.jgss.Oid;
38  
39  public class SpnegoLoginService extends AbstractLifeCycle implements LoginService
40  {
41      private static final Logger LOG = Log.getLogger(SpnegoLoginService.class);
42  
43      protected IdentityService _identityService;// = new LdapIdentityService();
44      protected String _name;
45      private String _config;
46  
47      private String _targetName;
48  
49      public SpnegoLoginService()
50      {
51  
52      }
53  
54      public SpnegoLoginService( String name )
55      {
56          setName(name);
57      }
58  
59      public SpnegoLoginService( String name, String config )
60      {
61          setName(name);
62          setConfig(config);
63      }
64  
65      @Override
66      public String getName()
67      {
68          return _name;
69      }
70  
71      public void setName(String name)
72      {
73          if (isRunning())
74          {
75              throw new IllegalStateException("Running");
76          }
77  
78          _name = name;
79      }
80  
81      public String getConfig()
82      {
83          return _config;
84      }
85  
86      public void setConfig( String config )
87      {
88          if (isRunning())
89          {
90              throw new IllegalStateException("Running");
91          }
92  
93          _config = config;
94      }
95  
96  
97  
98      @Override
99      protected void doStart() throws Exception
100     {
101         Properties properties = new Properties();
102         Resource resource = Resource.newResource(_config);
103         properties.load(resource.getInputStream());
104 
105         _targetName = properties.getProperty("targetName");
106 
107         LOG.debug("Target Name {}", _targetName);
108 
109         super.doStart();
110     }
111 
112     /**
113      * username will be null since the credentials will contain all the relevant info
114      */
115     @Override
116     public UserIdentity login(String username, Object credentials, ServletRequest request)
117     {
118         String encodedAuthToken = (String)credentials;
119 
120         byte[] authToken = B64Code.decode(encodedAuthToken);
121 
122         GSSManager manager = GSSManager.getInstance();
123         try
124         {
125             Oid krb5Oid = new Oid("1.3.6.1.5.5.2"); // http://java.sun.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
126             GSSName gssName = manager.createName(_targetName,null);
127             GSSCredential serverCreds = manager.createCredential(gssName,GSSCredential.INDEFINITE_LIFETIME,krb5Oid,GSSCredential.ACCEPT_ONLY);
128             GSSContext gContext = manager.createContext(serverCreds);
129 
130             if (gContext == null)
131             {
132                 LOG.debug("SpnegoUserRealm: failed to establish GSSContext");
133             }
134             else
135             {
136                 while (!gContext.isEstablished())
137                 {
138                     authToken = gContext.acceptSecContext(authToken,0,authToken.length);
139                 }
140                 if (gContext.isEstablished())
141                 {
142                     String clientName = gContext.getSrcName().toString();
143                     String role = clientName.substring(clientName.indexOf('@') + 1);
144 
145                     LOG.debug("SpnegoUserRealm: established a security context");
146                     LOG.debug("Client Principal is: " + gContext.getSrcName());
147                     LOG.debug("Server Principal is: " + gContext.getTargName());
148                     LOG.debug("Client Default Role: " + role);
149 
150                     SpnegoUserPrincipal user = new SpnegoUserPrincipal(clientName,authToken);
151 
152                     Subject subject = new Subject();
153                     subject.getPrincipals().add(user);
154 
155                     return _identityService.newUserIdentity(subject,user, new String[]{role});
156                 }
157             }
158 
159         }
160         catch (GSSException gsse)
161         {
162             LOG.warn(gsse);
163         }
164 
165         return null;
166     }
167 
168     @Override
169     public boolean validate(UserIdentity user)
170     {
171         return false;
172     }
173 
174     @Override
175     public IdentityService getIdentityService()
176     {
177         return _identityService;
178     }
179 
180     @Override
181     public void setIdentityService(IdentityService service)
182     {
183         _identityService = service;
184     }
185 
186     @Override
187     public void logout(UserIdentity user) 
188     {
189         // TODO Auto-generated method stub
190     }
191 
192 }