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.cas;
20  
21  import java.net.URI;
22  import org.apache.commons.lang3.StringUtils;
23  import org.apache.syncope.sra.security.PublicRouteMatcher;
24  import org.apache.syncope.sra.security.web.server.DoNothingIfCommittedServerRedirectStrategy;
25  import org.apache.syncope.sra.session.SessionUtils;
26  import org.jasig.cas.client.Protocol;
27  import org.jasig.cas.client.util.CommonUtils;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  import org.springframework.security.web.server.ServerRedirectStrategy;
31  import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
32  import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;
33  import org.springframework.web.server.ServerWebExchange;
34  import org.springframework.web.server.WebFilter;
35  import org.springframework.web.server.WebFilterChain;
36  import reactor.core.publisher.Mono;
37  
38  public class CASAuthenticationRequestWebFilter implements WebFilter {
39  
40      private static final Logger LOG = LoggerFactory.getLogger(CASAuthenticationRequestWebFilter.class);
41  
42      private final ServerWebExchangeMatcher matcher;
43  
44      private final Protocol protocol;
45  
46      /**
47       * The URL to the CAS Server login.
48       */
49      private final String casServerLoginUrl;
50  
51      private ServerRedirectStrategy authenticationRedirectStrategy = new DoNothingIfCommittedServerRedirectStrategy();
52  
53      public CASAuthenticationRequestWebFilter(
54              final PublicRouteMatcher publicRouteMatcher,
55              final Protocol protocol,
56              final String casServerUrlPrefix) {
57  
58          matcher = ServerWebExchangeMatchers.matchers(
59                  publicRouteMatcher,
60                  CASUtils.ticketAvailable(protocol),
61                  SessionUtils.authInSession());
62          this.protocol = protocol;
63          casServerLoginUrl = StringUtils.appendIfMissing(casServerUrlPrefix, "/") + "login";
64      }
65  
66      public void setAuthenticationRedirectStrategy(final ServerRedirectStrategy authenticationRedirectStrategy) {
67          this.authenticationRedirectStrategy = authenticationRedirectStrategy;
68      }
69  
70      @Override
71      public Mono<Void> filter(final ServerWebExchange exchange, final WebFilterChain chain) {
72          return matcher.matches(exchange).
73                  filter(matchResult -> !matchResult.isMatch()).
74                  switchIfEmpty(chain.filter(exchange).then(Mono.empty())).
75                  flatMap(r -> exchange.getSession()).
76                  flatMap(session -> {
77                      session.getAttributes().
78                              put(SessionUtils.INITIAL_REQUEST_URI, exchange.getRequest().getURI());
79  
80                      LOG.debug("no ticket and no assertion found");
81  
82                      String serviceUrl = CASUtils.constructServiceUrl(exchange, protocol);
83                      LOG.debug("Constructed service url: {}", serviceUrl);
84  
85                      String urlToRedirectTo = CommonUtils.constructRedirectUrl(
86                              casServerLoginUrl,
87                              protocol.getServiceParameterName(),
88                              serviceUrl,
89                              false,
90                              false,
91                              null);
92                      LOG.debug("redirecting to \"{}\"", urlToRedirectTo);
93  
94                      return authenticationRedirectStrategy.sendRedirect(exchange, URI.create(urlToRedirectTo));
95                  });
96      }
97  }