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.sra.security.saml2;
20  
21  import org.apache.syncope.sra.security.pac4j.NoOpSessionStore;
22  import org.apache.syncope.sra.security.pac4j.RedirectionActionUtils;
23  import org.apache.syncope.sra.security.pac4j.ServerWebExchangeContext;
24  import org.pac4j.saml.client.SAML2Client;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
28  import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher.MatchResult;
29  import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;
30  import org.springframework.web.server.ServerWebExchange;
31  import org.springframework.web.server.WebFilter;
32  import org.springframework.web.server.WebFilterChain;
33  import reactor.core.publisher.Mono;
34  
35  public class SAML2WebSsoAuthenticationRequestWebFilter implements WebFilter {
36  
37      private static final Logger LOG = LoggerFactory.getLogger(SAML2WebSsoAuthenticationRequestWebFilter.class);
38  
39      public static final String AUTHENTICATE_URL = "/saml2/authenticate";
40  
41      private static final ServerWebExchangeMatcher MATCHER =
42              ServerWebExchangeMatchers.pathMatchers(AUTHENTICATE_URL);
43  
44      private final SAML2Client saml2Client;
45  
46      public SAML2WebSsoAuthenticationRequestWebFilter(final SAML2Client saml2Client) {
47          this.saml2Client = saml2Client;
48      }
49  
50      @Override
51      public Mono<Void> filter(final ServerWebExchange exchange, final WebFilterChain chain) {
52          return MATCHER.matches(exchange).
53                  filter(MatchResult::isMatch).
54                  switchIfEmpty(chain.filter(exchange).then(Mono.empty())).
55                  flatMap(matchResult -> {
56                      LOG.debug("Creating SAML2 SP Authentication Request for IDP[{}]",
57                              saml2Client.getIdentityProviderResolvedEntityId());
58  
59                      ServerWebExchangeContext swec = new ServerWebExchangeContext(exchange);
60  
61                      return saml2Client.getRedirectionAction(swec, NoOpSessionStore.INSTANCE).
62                              map(action -> RedirectionActionUtils.handle(action, swec)).
63                              orElseThrow(() -> new IllegalStateException("No action generated"));
64                  }).onErrorResume(Mono::error);
65      }
66  }