1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 }