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.io.IOException;
22  
23  import javax.security.auth.Subject;
24  import javax.security.auth.callback.Callback;
25  import javax.security.auth.callback.CallbackHandler;
26  import javax.security.auth.callback.UnsupportedCallbackException;
27  import javax.security.auth.message.callback.CallerPrincipalCallback;
28  import javax.security.auth.message.callback.CertStoreCallback;
29  import javax.security.auth.message.callback.GroupPrincipalCallback;
30  import javax.security.auth.message.callback.PasswordValidationCallback;
31  import javax.security.auth.message.callback.PrivateKeyCallback;
32  import javax.security.auth.message.callback.SecretKeyCallback;
33  import javax.security.auth.message.callback.TrustStoreCallback;
34  
35  import org.eclipse.jetty.security.LoginService;
36  import org.eclipse.jetty.security.authentication.LoginCallback;
37  import org.eclipse.jetty.security.authentication.LoginCallbackImpl;
38  import org.eclipse.jetty.security.jaspi.callback.CredentialValidationCallback;
39  import org.eclipse.jetty.server.UserIdentity;
40  
41  /**
42   * Idiot class required by jaspi stupidity
43   */
44  public class ServletCallbackHandler implements CallbackHandler
45  {
46      private final LoginService _loginService;
47  
48      private final ThreadLocal<CallerPrincipalCallback> _callerPrincipals = new ThreadLocal<CallerPrincipalCallback>();
49      private final ThreadLocal<GroupPrincipalCallback> _groupPrincipals = new ThreadLocal<GroupPrincipalCallback>();
50  
51      public ServletCallbackHandler(LoginService loginService)
52      {
53          _loginService = loginService;
54      }
55  
56      public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
57      {
58          for (Callback callback : callbacks)
59          {
60              // jaspi to server communication
61              if (callback instanceof CallerPrincipalCallback)
62              {
63                  _callerPrincipals.set((CallerPrincipalCallback) callback);
64              }
65              else if (callback instanceof GroupPrincipalCallback)
66              {
67                  _groupPrincipals.set((GroupPrincipalCallback) callback);
68              }
69              else if (callback instanceof PasswordValidationCallback)
70              {
71                  PasswordValidationCallback passwordValidationCallback = (PasswordValidationCallback) callback;
72                  Subject subject = passwordValidationCallback.getSubject();
73  
74                  UserIdentity user = _loginService.login(passwordValidationCallback.getUsername(),passwordValidationCallback.getPassword(), null);
75                  
76                  if (user!=null)
77                  {
78                      passwordValidationCallback.setResult(true);
79                      passwordValidationCallback.getSubject().getPrincipals().addAll(user.getSubject().getPrincipals());
80                      passwordValidationCallback.getSubject().getPrivateCredentials().add(user);
81                  }
82              }
83              else if (callback instanceof CredentialValidationCallback)
84              {
85                  CredentialValidationCallback credentialValidationCallback = (CredentialValidationCallback) callback;
86                  Subject subject = credentialValidationCallback.getSubject();
87                  LoginCallback loginCallback = new LoginCallbackImpl(subject,
88                          credentialValidationCallback.getUsername(),
89                          credentialValidationCallback.getCredential());
90  
91                  UserIdentity user = _loginService.login(credentialValidationCallback.getUsername(),credentialValidationCallback.getCredential(), null);
92  
93                  if (user!=null)
94                  {
95                      loginCallback.setUserPrincipal(user.getUserPrincipal());
96                      credentialValidationCallback.getSubject().getPrivateCredentials().add(loginCallback);
97                      credentialValidationCallback.setResult(true);
98                      credentialValidationCallback.getSubject().getPrincipals().addAll(user.getSubject().getPrincipals());
99                      credentialValidationCallback.getSubject().getPrivateCredentials().add(user);
100                 }
101             }
102             // server to jaspi communication
103             // TODO implement these
104             else if (callback instanceof CertStoreCallback)
105             {
106             }
107             else if (callback instanceof PrivateKeyCallback)
108             {
109             }
110             else if (callback instanceof SecretKeyCallback)
111             {
112             }
113             else if (callback instanceof TrustStoreCallback)
114             {
115             }
116             else
117             {
118                 throw new UnsupportedCallbackException(callback);
119             }
120         }
121     }
122 
123     public CallerPrincipalCallback getThreadCallerPrincipalCallback()
124     {
125         CallerPrincipalCallback callerPrincipalCallback = _callerPrincipals.get();
126         _callerPrincipals.set(null);
127         return callerPrincipalCallback;
128     }
129 
130     public GroupPrincipalCallback getThreadGroupPrincipalCallback()
131     {
132         GroupPrincipalCallback groupPrincipalCallback = _groupPrincipals.get();
133         _groupPrincipals.set(null);
134         return groupPrincipalCallback;
135     }
136 }