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.client.ui.commons.resources.saml2sp4ui;
20  
21  import java.io.IOException;
22  import java.util.Base64;
23  import java.util.stream.Stream;
24  import javax.servlet.http.HttpServletRequest;
25  import javax.ws.rs.core.HttpHeaders;
26  import javax.ws.rs.core.MediaType;
27  import javax.ws.rs.core.Response;
28  import org.apache.commons.lang3.StringUtils;
29  import org.apache.syncope.client.ui.commons.SAML2SP4UIConstants;
30  import org.apache.syncope.common.lib.saml2.SAML2Constants;
31  import org.apache.syncope.common.lib.saml2.SAML2Request;
32  import org.apache.syncope.common.lib.saml2.SAML2Response;
33  import org.apache.wicket.Session;
34  import org.apache.wicket.request.resource.AbstractResource;
35  import org.slf4j.Logger;
36  import org.slf4j.LoggerFactory;
37  
38  public abstract class AbstractSAML2SP4UIResource extends AbstractResource {
39  
40      private static final long serialVersionUID = 865306127846395310L;
41  
42      protected static final Logger LOG = LoggerFactory.getLogger(AbstractSAML2SP4UIResource.class);
43  
44      protected String spEntityID(final Attributes attributes) {
45          HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
46          return StringUtils.substringBefore(request.getRequestURL().toString(), SAML2SP4UIConstants.URL_CONTEXT);
47      }
48  
49      protected ResourceResponse send(final SAML2Request request) {
50          Session.get().setAttribute(SAML2SP4UIConstants.SAML2SP4UI_IDP_ENTITY_ID, request.getIdpEntityID());
51  
52          ResourceResponse response = new ResourceResponse();
53          response.getHeaders().addHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store");
54          response.getHeaders().addHeader("Pragma", "no-cache");
55          switch (request.getBindingType()) {
56              case REDIRECT:
57                  response.setStatusCode(Response.Status.FOUND.getStatusCode());
58                  response.getHeaders().addHeader(HttpHeaders.LOCATION, request.getContent());
59                  break;
60  
61              case POST:
62              default:
63                  response.setContentType(MediaType.TEXT_HTML);
64                  response.setWriteCallback(new WriteCallback() {
65  
66                      @Override
67                      public void writeData(final Attributes attributes) throws IOException {
68                          attributes.getResponse().
69                                  write(new String(Base64.getMimeDecoder().decode(request.getContent())));
70                      }
71                  });
72          }
73          return response;
74      }
75  
76      protected SAML2Response buildResponse(
77              final Attributes attributes,
78              final String samlResponse,
79              final String relayState) {
80  
81          SAML2Response response = new SAML2Response();
82  
83          response.setIdpEntityID((String) Session.get().getAttribute(SAML2SP4UIConstants.SAML2SP4UI_IDP_ENTITY_ID));
84          if (StringUtils.isBlank(response.getIdpEntityID())) {
85              response.setIdpEntityID(attributes.getRequest().getQueryParameters().
86                      getParameterValue(SAML2SP4UIConstants.SAML2SP4UI_IDP_ENTITY_ID).toOptionalString());
87              if (StringUtils.isBlank(response.getIdpEntityID())) {
88                  Stream.of(((HttpServletRequest) attributes.getRequest().getContainerRequest()).getCookies()).
89                          filter(cookie -> SAML2SP4UIConstants.SAML2SP4UI_IDP_ENTITY_ID.equals(cookie.getName())).
90                          findFirst().ifPresent(cookie -> response.setIdpEntityID(cookie.getValue()));
91              }
92          }
93  
94          response.setSpEntityID(spEntityID(attributes));
95          response.setUrlContext(SAML2SP4UIConstants.URL_CONTEXT);
96          response.setSamlResponse(samlResponse);
97          response.setRelayState(relayState);
98  
99          return response;
100     }
101 
102     protected SAML2Response extract(final Attributes attributes) {
103         String samlResponse = attributes.getRequest().getRequestParameters().
104                 getParameterValue(SAML2Constants.SAML_RESPONSE).toOptionalString();
105         LOG.debug("Received SAML Response: {}", samlResponse);
106 
107         String relayState = attributes.getRequest().getRequestParameters().
108                 getParameterValue(SAML2Constants.RELAY_STATE).toOptionalString();
109         LOG.debug("Received Relay State: {}", relayState);
110 
111         return buildResponse(attributes, samlResponse, relayState);
112     }
113 }