View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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.jaspi;
20  
21  import java.security.Principal;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.Set;
26  
27  import javax.security.auth.Subject;
28  import javax.security.auth.message.AuthException;
29  import javax.security.auth.message.config.AuthConfigFactory;
30  import javax.security.auth.message.config.AuthConfigProvider;
31  import javax.security.auth.message.config.RegistrationListener;
32  import javax.security.auth.message.config.ServerAuthConfig;
33  import javax.servlet.ServletContext;
34  
35  import org.eclipse.jetty.security.Authenticator;
36  import org.eclipse.jetty.security.Authenticator.AuthConfiguration;
37  import org.eclipse.jetty.security.DefaultAuthenticatorFactory;
38  import org.eclipse.jetty.security.IdentityService;
39  import org.eclipse.jetty.security.LoginService;
40  import org.eclipse.jetty.server.Server;
41  import org.eclipse.jetty.util.log.Log;
42  import org.eclipse.jetty.util.log.Logger;
43  
44  public class JaspiAuthenticatorFactory extends DefaultAuthenticatorFactory
45  {
46      private static final Logger LOG = Log.getLogger(JaspiAuthenticatorFactory.class);
47  
48      private static String MESSAGE_LAYER = "HTTP";
49      
50      private Subject _serviceSubject;
51      private String _serverName;
52      
53  
54      /* ------------------------------------------------------------ */
55      /**
56       * @return the serviceSubject
57       */
58      public Subject getServiceSubject()
59      {
60          return _serviceSubject;
61      }
62  
63      /* ------------------------------------------------------------ */
64      /**
65       * @param serviceSubject the serviceSubject to set
66       */
67      public void setServiceSubject(Subject serviceSubject)
68      {
69          _serviceSubject = serviceSubject;
70      }
71  
72      /* ------------------------------------------------------------ */
73      /**
74       * @return the serverName
75       */
76      public String getServerName()
77      {
78          return _serverName;
79      }
80  
81      /* ------------------------------------------------------------ */
82      /**
83       * @param serverName the serverName to set
84       */
85      public void setServerName(String serverName)
86      {
87          _serverName = serverName;
88      }
89  
90      /* ------------------------------------------------------------ */
91      public Authenticator getAuthenticator(Server server, ServletContext context, AuthConfiguration configuration, IdentityService identityService, LoginService loginService)
92      {
93          Authenticator authenticator=null;
94          try 
95          {
96              AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory();
97              RegistrationListener listener = new RegistrationListener()
98              {
99                  public void notify(String layer, String appContext)
100                 {}
101             };
102 
103             Subject serviceSubject=findServiceSubject(server);
104             String serverName=findServerName(server,serviceSubject);
105             String appContext = serverName + " " + context.getContextPath();
106             
107             AuthConfigProvider authConfigProvider = authConfigFactory.getConfigProvider(MESSAGE_LAYER,appContext,listener);
108   
109             if (authConfigProvider != null)
110             {
111                 ServletCallbackHandler servletCallbackHandler = new ServletCallbackHandler(loginService);
112                 ServerAuthConfig serverAuthConfig = authConfigProvider.getServerAuthConfig(MESSAGE_LAYER,appContext,servletCallbackHandler);
113                 if (serverAuthConfig != null)
114                 {
115                     Map map = new HashMap();
116                     for (String key : configuration.getInitParameterNames())
117                         map.put(key,configuration.getInitParameter(key));
118                     authenticator= new JaspiAuthenticator(serverAuthConfig,map,servletCallbackHandler,
119                                 serviceSubject,true, identityService);
120                 }
121             }
122         } 
123         catch (AuthException e) 
124         {
125             LOG.warn(e);
126         }
127         return authenticator;
128     }
129 
130     /* ------------------------------------------------------------ */
131     /** Find a service Subject.
132      * If {@link #setServiceSubject(Subject)} has not been used to 
133      * set a subject, then the {@link Server#getBeans(Class)} method is
134      * used to look for a Subject.
135      */
136     protected Subject findServiceSubject(Server server)
137     {
138         if (_serviceSubject!=null)
139             return _serviceSubject;
140         List<Subject> subjects = (List<Subject>)server.getBeans(Subject.class);
141         if (subjects.size()>0)
142             return (Subject)subjects.get(0);
143         return null;
144     }
145 
146     /* ------------------------------------------------------------ */
147     /** Find a servername.
148      * If {@link #setServerName(String)} has not been called, then
149      * use the name of the a principal in the service subject.
150      * If not found, return "server".
151      */
152     protected String findServerName(Server server, Subject subject)
153     {
154         if (_serverName!=null)
155             return _serverName;
156         if (subject!=null)
157         {
158             Set<Principal> principals = subject.getPrincipals();
159             if (principals!=null && !principals.isEmpty())
160                 return principals.iterator().next().getName();
161         }
162         
163         return "server";
164     }
165 }