View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.wa.starter.pac4j.saml;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.io.InputStream;
24  import java.security.KeyStore;
25  import java.security.PrivateKey;
26  import java.security.cert.X509Certificate;
27  import java.util.Base64;
28  import org.apache.syncope.common.lib.to.SAML2SPEntityTO;
29  import org.apache.syncope.common.rest.api.service.SAML2SPEntityService;
30  import org.apache.syncope.wa.bootstrap.WARestClient;
31  import org.pac4j.saml.client.SAML2Client;
32  import org.pac4j.saml.metadata.keystore.BaseSAML2KeystoreGenerator;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  public class WASAML2ClientKeystoreGenerator extends BaseSAML2KeystoreGenerator {
37  
38      protected static final Logger LOG = LoggerFactory.getLogger(WASAML2ClientKeystoreGenerator.class);
39  
40      protected final WARestClient waRestClient;
41  
42      protected final SAML2Client saml2Client;
43  
44      public WASAML2ClientKeystoreGenerator(final WARestClient waRestClient, final SAML2Client saml2Client) {
45          super(saml2Client.getConfiguration());
46          this.waRestClient = waRestClient;
47          this.saml2Client = saml2Client;
48      }
49  
50      @Override
51      public boolean shouldGenerate() {
52          return true;
53      }
54  
55      @Override
56      protected void store(final KeyStore ks, final X509Certificate certificate, final PrivateKey privateKey)
57              throws Exception {
58  
59          try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
60              char[] password = saml2Configuration.getKeystorePassword().toCharArray();
61              ks.store(out, password);
62              out.flush();
63              String encodedKeystore = Base64.getEncoder().encodeToString(out.toByteArray());
64              LOG.debug("Encoded keystore {}", encodedKeystore);
65  
66              SAML2SPEntityTO entityTO;
67              try {
68                  entityTO = waRestClient.getService(SAML2SPEntityService.class).get(saml2Client.getName());
69                  entityTO.setKeystore(encodedKeystore);
70              } catch (Exception e) {
71                  LOG.debug("SP Entity {} not found, creating new", saml2Client.getName(), e);
72  
73                  entityTO = new SAML2SPEntityTO.Builder().
74                          key(saml2Client.getName()).
75                          keystore(encodedKeystore).
76                          build();
77              }
78  
79              LOG.debug("Storing SP Entity {}", entityTO);
80              waRestClient.getService(SAML2SPEntityService.class).set(entityTO);
81          }
82      }
83  
84      @Override
85      public InputStream retrieve() throws Exception {
86          try {
87              SAML2SPEntityTO spEntity = waRestClient.getService(SAML2SPEntityService.class).get(saml2Client.getName());
88  
89              LOG.debug("Retrieved keystore {}", spEntity.getKeystore());
90              return new ByteArrayInputStream(Base64.getDecoder().decode(spEntity.getKeystore()));
91          } catch (Exception e) {
92              String message = "Unable to fetch SAML2 SP keystore for " + saml2Client.getName();
93              LOG.error(message, e);
94              throw new Exception(message);
95          }
96      }
97  }