1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.security.jaspi.modules;
15
16 import java.io.IOException;
17 import java.security.Principal;
18
19 import javax.security.auth.Subject;
20 import javax.security.auth.callback.CallbackHandler;
21 import javax.security.auth.callback.UnsupportedCallbackException;
22 import javax.security.auth.message.AuthException;
23 import javax.security.auth.message.AuthStatus;
24 import javax.security.auth.message.MessageInfo;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27
28 import org.eclipse.jetty.http.security.Constraint;
29 import org.eclipse.jetty.http.security.Password;
30 import org.eclipse.jetty.util.B64Code;
31
32
33
34
35
36 public class ClientCertAuthModule extends BaseAuthModule
37 {
38
39 public ClientCertAuthModule()
40 {
41 }
42
43 public ClientCertAuthModule(CallbackHandler callbackHandler)
44 {
45 super(callbackHandler);
46 }
47
48 @Override
49 public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject,
50 Subject serviceSubject)
51 throws AuthException
52 {
53 HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
54 HttpServletResponse response = (HttpServletResponse) messageInfo.getResponseMessage();
55 java.security.cert.X509Certificate[] certs = (java.security.cert.X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
56
57 try
58 {
59
60 if (certs == null || certs.length == 0 || certs[0] == null)
61 {
62 response.sendError(HttpServletResponse.SC_FORBIDDEN,
63 "A client certificate is required for accessing this web application but the server's listener is not configured for mutual authentication (or the client did not provide a certificate).");
64 return AuthStatus.SEND_FAILURE;
65 }
66 Principal principal = certs[0].getSubjectDN();
67 if (principal == null) principal = certs[0].getIssuerDN();
68 final String username = principal == null ? "clientcert" : principal.getName();
69
70 final String password = new String(B64Code.encode(certs[0].getSignature()));
71
72
73 if (login(clientSubject, username, new Password(password), Constraint.__CERT_AUTH, messageInfo)) { return AuthStatus.SUCCESS; }
74
75 if (!isMandatory(messageInfo)) { return AuthStatus.SUCCESS; }
76 response.sendError(HttpServletResponse.SC_FORBIDDEN, "The provided client certificate does not correspond to a trusted user.");
77 return AuthStatus.SEND_FAILURE;
78 }
79 catch (IOException e)
80 {
81 throw new AuthException(e.getMessage());
82 }
83 catch (UnsupportedCallbackException e)
84 {
85 throw new AuthException(e.getMessage());
86 }
87
88 }
89 }