View Javadoc
1   /*
2    * Copyright 2005-2010 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.ws.soap.security.xwss.callback.jaas;
18  
19  import java.security.cert.X509Certificate;
20  import javax.security.auth.Subject;
21  import javax.security.auth.callback.Callback;
22  import javax.security.auth.callback.UnsupportedCallbackException;
23  import javax.security.auth.login.LoginContext;
24  import javax.security.auth.login.LoginException;
25  
26  import com.sun.xml.wss.impl.callback.CertificateValidationCallback;
27  
28  /**
29   * Provides basic support for integrating with JAAS and certificates. Requires the <code>loginContextName</code> to be
30   * set.Requires a <code>LoginContext</code> which handles <code>X500Principal</code>s.
31   * <p/>
32   * This class only handles <code>CertificateValidationCallback</code>s, and throws an
33   * <code>UnsupportedCallbackException</code> for others.
34   *
35   * @author Arjen Poutsma
36   * @see javax.security.auth.x500.X500Principal
37   * @see #setLoginContextName(String)
38   * @since 1.0.0
39   */
40  public class JaasCertificateValidationCallbackHandler extends AbstractJaasValidationCallbackHandler {
41  
42      /**
43       * Handles  <code>CertificateValidationCallback</code>s, and throws an <code>UnsupportedCallbackException</code> for
44       * others
45       *
46       * @throws UnsupportedCallbackException when the callback is not supported
47       */
48      @Override
49      protected final void handleInternal(Callback callback) throws UnsupportedCallbackException {
50          if (callback instanceof CertificateValidationCallback) {
51              ((CertificateValidationCallback) callback).setValidator(new JaasCertificateValidator());
52          }
53          else {
54              throw new UnsupportedCallbackException(callback);
55          }
56      }
57  
58      private class JaasCertificateValidator implements CertificateValidationCallback.CertificateValidator {
59  
60          public boolean validate(X509Certificate certificate)
61                  throws CertificateValidationCallback.CertificateValidationException {
62              Subject subject = new Subject();
63              subject.getPrincipals().add(certificate.getSubjectX500Principal());
64              LoginContext loginContext;
65              try {
66                  loginContext = new LoginContext(getLoginContextName(), subject);
67              }
68              catch (LoginException ex) {
69                  throw new CertificateValidationCallback.CertificateValidationException(ex);
70              }
71              catch (SecurityException ex) {
72                  throw new CertificateValidationCallback.CertificateValidationException(ex);
73              }
74  
75              try {
76                  loginContext.login();
77                  Subject subj = loginContext.getSubject();
78                  if (!subj.getPrincipals().isEmpty()) {
79                      if (logger.isDebugEnabled()) {
80                          logger.debug("Authentication request for certificate with DN [" +
81                                  certificate.getSubjectX500Principal().getName() + "] successful");
82                      }
83                      return true;
84                  }
85                  else {
86                      if (logger.isDebugEnabled()) {
87                          logger.debug("Authentication request for certificate with DN [" +
88                                  certificate.getSubjectX500Principal().getName() + "] failed");
89                      }
90                      return false;
91                  }
92              }
93              catch (LoginException ex) {
94                  if (logger.isDebugEnabled()) {
95                      logger.debug("Authentication request for certificate with DN [" +
96                              certificate.getSubjectX500Principal().getName() + "] failed");
97                  }
98                  return false;
99              }
100         }
101     }
102 }