View Javadoc

1   // ========================================================================
2   // Copyright (c) 2008-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.security.jaspi;
15  
16  import java.security.Principal;
17  import java.util.HashMap;
18  import java.util.List;
19  import java.util.Map;
20  import java.util.Set;
21  
22  import javax.security.auth.Subject;
23  import javax.security.auth.message.AuthException;
24  import javax.security.auth.message.config.AuthConfigFactory;
25  import javax.security.auth.message.config.AuthConfigProvider;
26  import javax.security.auth.message.config.RegistrationListener;
27  import javax.security.auth.message.config.ServerAuthConfig;
28  import javax.servlet.ServletContext;
29  
30  import org.eclipse.jetty.security.Authenticator;
31  import org.eclipse.jetty.security.DefaultAuthenticatorFactory;
32  import org.eclipse.jetty.security.IdentityService;
33  import org.eclipse.jetty.security.LoginService;
34  import org.eclipse.jetty.security.Authenticator.AuthConfiguration;
35  import org.eclipse.jetty.server.Server;
36  import org.eclipse.jetty.util.log.Log;
37  import org.eclipse.jetty.util.log.Logger;
38  
39  public class JaspiAuthenticatorFactory extends DefaultAuthenticatorFactory
40  {
41      private static final Logger LOG = Log.getLogger(JaspiAuthenticatorFactory.class);
42  
43      private static String MESSAGE_LAYER = "HTTP";
44      
45      private Subject _serviceSubject;
46      private String _serverName;
47      
48  
49      /* ------------------------------------------------------------ */
50      /**
51       * @return the serviceSubject
52       */
53      public Subject getServiceSubject()
54      {
55          return _serviceSubject;
56      }
57  
58      /* ------------------------------------------------------------ */
59      /**
60       * @param serviceSubject the serviceSubject to set
61       */
62      public void setServiceSubject(Subject serviceSubject)
63      {
64          _serviceSubject = serviceSubject;
65      }
66  
67      /* ------------------------------------------------------------ */
68      /**
69       * @return the serverName
70       */
71      public String getServerName()
72      {
73          return _serverName;
74      }
75  
76      /* ------------------------------------------------------------ */
77      /**
78       * @param serverName the serverName to set
79       */
80      public void setServerName(String serverName)
81      {
82          _serverName = serverName;
83      }
84  
85      /* ------------------------------------------------------------ */
86      public Authenticator getAuthenticator(Server server, ServletContext context, AuthConfiguration configuration, IdentityService identityService, LoginService loginService)
87      {
88          Authenticator authenticator=null;
89          try 
90          {
91              AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory();
92              RegistrationListener listener = new RegistrationListener()
93              {
94                  public void notify(String layer, String appContext)
95                  {}
96              };
97  
98              Subject serviceSubject=findServiceSubject(server);
99              String serverName=findServerName(server,serviceSubject);
100             
101             System.err.println("authconfigfactory="+authConfigFactory+" serviceSubject="+serviceSubject+" serverName="+serverName);
102             
103             String appContext = serverName + " " + context.getContextPath();
104             
105             System.err.println("appcontext="+appContext);
106             AuthConfigProvider authConfigProvider = authConfigFactory.getConfigProvider(MESSAGE_LAYER,appContext,listener);
107             System.err.println("authconfigProvider="+authConfigProvider);
108             if (authConfigProvider != null)
109             {
110                 ServletCallbackHandler servletCallbackHandler = new ServletCallbackHandler(loginService);
111                 ServerAuthConfig serverAuthConfig = authConfigProvider.getServerAuthConfig(MESSAGE_LAYER,appContext,servletCallbackHandler);
112                 if (serverAuthConfig != null)
113                 {
114                     Map map = new HashMap();
115                     for (String key : configuration.getInitParameterNames())
116                         map.put(key,configuration.getInitParameter(key));
117                     authenticator= new JaspiAuthenticator(serverAuthConfig,map,servletCallbackHandler,
118                                 serviceSubject,true, identityService);
119                 }
120             }
121         } 
122         catch (AuthException e) 
123         {
124             LOG.warn(e);
125         }
126         return authenticator;
127     }
128 
129     /* ------------------------------------------------------------ */
130     /** Find a service Subject.
131      * If {@link #setServiceSubject(Subject)} has not been used to 
132      * set a subject, then the {@link Server#getBeans(Class)} method is
133      * used to look for a Subject.
134      */
135     protected Subject findServiceSubject(Server server)
136     {
137         if (_serviceSubject!=null)
138             return _serviceSubject;
139         List subjects = server.getBeans(Subject.class);
140         if (subjects.size()>0)
141             return (Subject)subjects.get(0);
142         return null;
143     }
144 
145     /* ------------------------------------------------------------ */
146     /** Find a servername.
147      * If {@link #setServerName(String)} has not been called, then
148      * use the name of the a principal in the service subject.
149      * If not found, return "server".
150      */
151     protected String findServerName(Server server, Subject subject)
152     {
153         if (_serverName!=null)
154             return _serverName;
155         if (subject!=null)
156         {
157             Set<Principal> principals = subject.getPrincipals();
158             if (principals!=null && !principals.isEmpty())
159                 return principals.iterator().next().getName();
160         }
161         
162         return "server";
163     }
164 }