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.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 contextPath=context.getContextPath();
106             if (contextPath==null || contextPath.length()==0)
107                 contextPath="/";
108             String appContext = serverName + " " + context.getContextPath();
109             
110             AuthConfigProvider authConfigProvider = authConfigFactory.getConfigProvider(MESSAGE_LAYER,appContext,listener);
111   
112             if (authConfigProvider != null)
113             {
114                 ServletCallbackHandler servletCallbackHandler = new ServletCallbackHandler(loginService);
115                 ServerAuthConfig serverAuthConfig = authConfigProvider.getServerAuthConfig(MESSAGE_LAYER,appContext,servletCallbackHandler);
116                 if (serverAuthConfig != null)
117                 {
118                     Map map = new HashMap();
119                     for (String key : configuration.getInitParameterNames())
120                         map.put(key,configuration.getInitParameter(key));
121                     authenticator= new JaspiAuthenticator(serverAuthConfig,map,servletCallbackHandler,
122                                 serviceSubject,true, identityService);
123                 }
124             }
125         } 
126         catch (AuthException e) 
127         {
128             LOG.warn(e);
129         }
130         return authenticator;
131     }
132 
133     /* ------------------------------------------------------------ */
134     /** Find a service Subject.
135      * If {@link #setServiceSubject(Subject)} has not been used to 
136      * set a subject, then the {@link Server#getBeans(Class)} method is
137      * used to look for a Subject.
138      * @param server the server to pull the Subject from
139      * @return the subject
140      */
141     protected Subject findServiceSubject(Server server)
142     {
143         if (_serviceSubject!=null)
144             return _serviceSubject;
145         List<Subject> subjects = (List<Subject>)server.getBeans(Subject.class);
146         if (subjects.size()>0)
147             return (Subject)subjects.get(0);
148         return null;
149     }
150 
151     /* ------------------------------------------------------------ */
152     /** Find a servername.
153      * If {@link #setServerName(String)} has not been called, then
154      * use the name of the a principal in the service subject.
155      * If not found, return "server".
156      * @param server not used
157      * @param subject the subject to use
158      * @return the server name from the subject (or default value if not found in subject or principals)
159      */
160     protected String findServerName(Server server, Subject subject)
161     {
162         if (_serverName!=null)
163             return _serverName;
164         if (subject!=null)
165         {
166             Set<Principal> principals = subject.getPrincipals();
167             if (principals!=null && !principals.isEmpty())
168                 return principals.iterator().next().getName();
169         }
170         
171         return "server";
172     }
173 }