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.SessionConfig;
22 import org.apache.syncope.sra.security.pac4j.NoOpSessionStore;
23 import org.apache.syncope.sra.security.pac4j.RedirectionActionUtils;
24 import org.apache.syncope.sra.security.pac4j.ServerWebExchangeContext;
25 import org.pac4j.saml.client.SAML2Client;
26 import org.pac4j.saml.credentials.SAML2Credentials;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29 import org.springframework.cache.CacheManager;
30 import org.springframework.security.core.Authentication;
31 import org.springframework.security.web.server.WebFilterExchange;
32 import org.springframework.security.web.server.authentication.logout.ServerLogoutHandler;
33 import reactor.core.publisher.Mono;
34
35 public class SAML2RequestServerLogoutHandler implements ServerLogoutHandler {
36
37 private static final Logger LOG = LoggerFactory.getLogger(SAML2RequestServerLogoutHandler.class);
38
39 private final SAML2Client saml2Client;
40
41 private final CacheManager cacheManager;
42
43 public SAML2RequestServerLogoutHandler(final SAML2Client saml2Client, final CacheManager cacheManager) {
44 this.saml2Client = saml2Client;
45 this.cacheManager = cacheManager;
46 }
47
48 @Override
49 public Mono<Void> logout(final WebFilterExchange exchange, final Authentication authentication) {
50 return exchange.getExchange().getSession().
51 flatMap(session -> {
52 SAML2Credentials credentials = (SAML2Credentials) authentication.getPrincipal();
53
54 LOG.debug("Creating SAML2 SP Logout Request for IDP[{}] and Profile[{}]",
55 saml2Client.getIdentityProviderResolvedEntityId(), credentials.getUserProfile());
56
57 ServerWebExchangeContext swec = new ServerWebExchangeContext(exchange.getExchange());
58
59 cacheManager.getCache(SessionConfig.DEFAULT_CACHE).evictIfPresent(session.getId());
60 return session.invalidate().then(
61 saml2Client.getLogoutAction(swec,
62 NoOpSessionStore.INSTANCE, credentials.getUserProfile(), null).
63 map(action -> RedirectionActionUtils.handle(action, swec)).
64 orElseThrow(() -> new IllegalStateException("No action generated")));
65 }).onErrorResume(Mono::error);
66 }
67 }