1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.sra.filters;
20
21 import java.util.Objects;
22 import java.util.Optional;
23 import org.apache.commons.lang3.StringUtils;
24 import org.apache.syncope.sra.SessionConfig;
25 import org.springframework.beans.factory.annotation.Autowired;
26 import org.springframework.cache.CacheManager;
27 import org.springframework.cloud.gateway.filter.GatewayFilter;
28 import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
29 import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory.NameConfig;
30 import org.springframework.security.core.context.SecurityContext;
31 import org.springframework.security.oauth2.core.oidc.StandardClaimNames;
32 import org.springframework.security.oauth2.core.oidc.user.OidcUser;
33 import org.springframework.security.oauth2.core.user.OAuth2User;
34 import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
35 import org.springframework.session.Session;
36 import reactor.core.publisher.Mono;
37
38 public class PrincipalToRequestHeaderFilterFactory extends AbstractGatewayFilterFactory<NameConfig> {
39
40 @Autowired
41 private CacheManager cacheManager;
42
43 public PrincipalToRequestHeaderFilterFactory() {
44 super(NameConfig.class);
45 }
46
47 @Override
48 public GatewayFilter apply(final NameConfig config) {
49 return (exchange, chain) -> exchange.getSession().
50 flatMap(session -> Mono.justOrEmpty(Optional.ofNullable(
51 cacheManager.getCache(SessionConfig.DEFAULT_CACHE).get(session.getId(), Session.class)).
52 map(cachedSession -> {
53 String principal = null;
54
55 SecurityContext ctx = cachedSession.getAttribute(
56 WebSessionServerSecurityContextRepository.DEFAULT_SPRING_SECURITY_CONTEXT_ATTR_NAME);
57 if (ctx != null && ctx.getAuthentication() != null) {
58 if (ctx.getAuthentication().getPrincipal() instanceof OidcUser) {
59 principal = ((OidcUser) ctx.getAuthentication().getPrincipal()).
60 getIdToken().getTokenValue();
61 } else if (ctx.getAuthentication().getPrincipal() instanceof OAuth2User) {
62 principal = Objects.toString(((OAuth2User) ctx.getAuthentication().getPrincipal()).
63 getAttributes().get(StandardClaimNames.PREFERRED_USERNAME), null);
64 } else {
65 principal = ctx.getAuthentication().getName();
66 }
67 }
68
69 return principal;
70 }))).
71 transform(principal -> principal.flatMap(p -> StringUtils.isEmpty(p)
72 ? chain.filter(exchange)
73 : chain.filter(exchange.mutate().
74 request(exchange.getRequest().mutate().
75 headers(headers -> headers.add(config.getName(), p)).build()).
76 build()))).
77 switchIfEmpty(chain.filter(exchange));
78 }
79 }