1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.sra.actuate;
20
21 import com.fasterxml.jackson.core.JsonProcessingException;
22 import com.fasterxml.jackson.databind.json.JsonMapper;
23 import java.time.OffsetDateTime;
24 import java.util.List;
25 import java.util.Objects;
26 import java.util.concurrent.ConcurrentMap;
27 import java.util.stream.Collectors;
28 import org.apache.syncope.common.lib.AMSession;
29 import org.apache.syncope.sra.SessionConfig;
30 import org.apache.syncope.sra.security.cas.CASAuthenticationToken;
31 import org.apache.syncope.sra.security.saml2.SAML2AuthenticationToken;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
35 import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
36 import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
37 import org.springframework.boot.actuate.endpoint.annotation.Selector;
38 import org.springframework.cache.Cache;
39 import org.springframework.cache.CacheManager;
40 import org.springframework.security.core.context.SecurityContext;
41 import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
42 import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
43 import org.springframework.session.MapSession;
44
45 @Endpoint(id = "sraSessions")
46 public class SRASessions {
47
48 protected static final Logger LOG = LoggerFactory.getLogger(SRASessions.class);
49
50 protected static final JsonMapper MAPPER = JsonMapper.builder().findAndAddModules().build();
51
52 protected final CacheManager cacheManager;
53
54 public SRASessions(final CacheManager cacheManager) {
55 this.cacheManager = cacheManager;
56 }
57
58 protected static AMSession map(final MapSession mapSession) {
59 SecurityContext ctx = mapSession.getAttribute(
60 WebSessionServerSecurityContextRepository.DEFAULT_SPRING_SECURITY_CONTEXT_ATTR_NAME);
61 if (ctx == null) {
62 return null;
63 }
64
65 AMSession session = new AMSession();
66 session.setKey(mapSession.getId());
67 session.setAuthenticationDate(mapSession.getCreationTime().atOffset(OffsetDateTime.now().getOffset()));
68
69 String principal;
70 if (ctx.getAuthentication() instanceof SAML2AuthenticationToken) {
71 principal = ((SAML2AuthenticationToken) ctx.getAuthentication()).getPrincipal().getNameId().getValue();
72 } else if (ctx.getAuthentication() instanceof CASAuthenticationToken) {
73 principal = ((CASAuthenticationToken) ctx.getAuthentication()).getPrincipal().getPrincipal().getName();
74 } else if (ctx.getAuthentication() instanceof OAuth2AuthenticationToken) {
75 principal = ((OAuth2AuthenticationToken) ctx.getAuthentication()).getPrincipal().getName();
76 } else {
77 principal = ctx.getAuthentication().getPrincipal().toString();
78 }
79 session.setPrincipal(principal);
80
81 try {
82 session.setJson(MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(ctx.getAuthentication()));
83 } catch (JsonProcessingException e) {
84 LOG.error("While serializing session {}", mapSession.getId(), e);
85 }
86
87 return session;
88 }
89
90 @ReadOperation
91 @SuppressWarnings("unchecked")
92 public List<AMSession> list() {
93 return ((ConcurrentMap<Object, Object>) cacheManager.getCache(SessionConfig.DEFAULT_CACHE).getNativeCache()).
94 values().stream().map(MapSession.class::cast).map(SRASessions::map).
95 filter(Objects::nonNull).collect(Collectors.toList());
96 }
97
98 @ReadOperation
99 public AMSession read(@Selector final String id) {
100 Cache.ValueWrapper value = cacheManager.getCache(SessionConfig.DEFAULT_CACHE).get(id);
101 if (value == null || !(value.get() instanceof MapSession)) {
102 return null;
103 }
104
105 return map((MapSession) value.get());
106 }
107
108 @DeleteOperation
109 public void delete(@Selector final String id) {
110 cacheManager.getCache(SessionConfig.DEFAULT_CACHE).evict(id);
111 }
112 }