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.modules;
20  
21  import java.io.IOException;
22  import java.nio.charset.StandardCharsets;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import javax.security.auth.Subject;
27  import javax.security.auth.callback.Callback;
28  import javax.security.auth.callback.CallbackHandler;
29  import javax.security.auth.callback.UnsupportedCallbackException;
30  import javax.security.auth.message.AuthException;
31  import javax.security.auth.message.AuthStatus;
32  import javax.security.auth.message.MessageInfo;
33  import javax.security.auth.message.MessagePolicy;
34  import javax.security.auth.message.callback.CallerPrincipalCallback;
35  import javax.security.auth.message.callback.GroupPrincipalCallback;
36  import javax.security.auth.message.config.ServerAuthContext;
37  import javax.security.auth.message.module.ServerAuthModule;
38  import javax.servlet.http.HttpServletRequest;
39  import javax.servlet.http.HttpServletResponse;
40  
41  import org.eclipse.jetty.security.authentication.LoginCallbackImpl;
42  import org.eclipse.jetty.security.jaspi.JaspiMessageInfo;
43  import org.eclipse.jetty.security.jaspi.callback.CredentialValidationCallback;
44  import org.eclipse.jetty.util.B64Code;
45  import org.eclipse.jetty.util.security.Credential;
46  import org.eclipse.jetty.util.security.Password;
47  
48  /**
49   * @deprecated use *ServerAuthentication
50   * @version $Rev: 4792 $ $Date: 2009-03-18 22:55:52 +0100 (Wed, 18 Mar 2009) $
51   */
52  public class BaseAuthModule implements ServerAuthModule, ServerAuthContext
53  {
54      private static final Class[] SUPPORTED_MESSAGE_TYPES = new Class[] { HttpServletRequest.class, HttpServletResponse.class };
55  
56      protected static final String LOGIN_SERVICE_KEY = "org.eclipse.jetty.security.jaspi.modules.LoginService";
57  
58      protected CallbackHandler callbackHandler;
59  
60      public Class[] getSupportedMessageTypes()
61      {
62          return SUPPORTED_MESSAGE_TYPES;
63      }
64  
65      public BaseAuthModule()
66      {
67      }
68  
69      public BaseAuthModule(CallbackHandler callbackHandler)
70      {
71          this.callbackHandler = callbackHandler;
72      }
73  
74      public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler handler, Map options) throws AuthException
75      {
76          this.callbackHandler = handler;
77      }
78  
79      public void cleanSubject(MessageInfo messageInfo, Subject subject) throws AuthException
80      {
81          // TODO apparently we either get the LoginCallback or the LoginService
82          // but not both :-(
83          // Set<LoginCallback> loginCallbacks =
84          // subject.getPrivateCredentials(LoginCallback.class);
85          // if (!loginCallbacks.isEmpty()) {
86          // LoginCallback loginCallback = loginCallbacks.iterator().next();
87          // }
88          // try {
89          // loginService.logout(subject);
90          // } catch (ServerAuthException e) {
91          // throw new AuthException(e.getMessage());
92          // }
93      }
94  
95      public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) throws AuthException
96      {
97          // servlets do not need secured responses
98          return AuthStatus.SEND_SUCCESS;
99      }
100 
101     public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException
102     {
103         return AuthStatus.SEND_FAILURE;
104     }
105 
106     /**
107      * @param messageInfo message info to examine for mandatory flag
108      * @return whether authentication is mandatory or optional
109      */
110     protected boolean isMandatory(MessageInfo messageInfo)
111     {
112         String mandatory = (String) messageInfo.getMap().get(JaspiMessageInfo.MANDATORY_KEY);
113         if (mandatory == null) return false;
114         return Boolean.valueOf(mandatory);
115     }
116 
117     protected boolean login(Subject clientSubject, String credentials, 
118                             String authMethod, MessageInfo messageInfo) 
119     throws IOException, UnsupportedCallbackException
120     {
121         credentials = credentials.substring(credentials.indexOf(' ')+1);
122         credentials = B64Code.decode(credentials, StandardCharsets.ISO_8859_1);
123         int i = credentials.indexOf(':');
124         String userName = credentials.substring(0,i);
125         String password = credentials.substring(i+1);
126         return login(clientSubject, userName, new Password(password), authMethod, messageInfo);
127     }
128 
129     protected boolean login(Subject clientSubject, String username, 
130                             Credential credential, String authMethod, 
131                             MessageInfo messageInfo) 
132     throws IOException, UnsupportedCallbackException
133     {
134         CredentialValidationCallback credValidationCallback = new CredentialValidationCallback(clientSubject, username, credential);
135         callbackHandler.handle(new Callback[] { credValidationCallback });
136         if (credValidationCallback.getResult())
137         {
138             Set<LoginCallbackImpl> loginCallbacks = clientSubject.getPrivateCredentials(LoginCallbackImpl.class);
139             if (!loginCallbacks.isEmpty())
140             {
141                 LoginCallbackImpl loginCallback = loginCallbacks.iterator().next();
142                 CallerPrincipalCallback callerPrincipalCallback = new CallerPrincipalCallback(clientSubject, loginCallback.getUserPrincipal());
143                 GroupPrincipalCallback groupPrincipalCallback = new GroupPrincipalCallback(clientSubject, loginCallback.getRoles());
144                 callbackHandler.handle(new Callback[] { callerPrincipalCallback, groupPrincipalCallback });
145             }
146             messageInfo.getMap().put(JaspiMessageInfo.AUTH_METHOD_KEY, authMethod);
147         }
148         return credValidationCallback.getResult();
149 
150     }
151 }