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