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