1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.shibboleth.idp.session.impl;
18
19 import java.security.SecureRandom;
20
21 import org.apache.commons.ssl.util.Hex;
22 import org.opensaml.util.storage.StorageService;
23 import org.opensaml.xml.util.DatatypeHelper;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import org.slf4j.MDC;
27
28 import edu.internet2.middleware.shibboleth.common.session.SessionManager;
29 import edu.internet2.middleware.shibboleth.idp.session.Session;
30
31
32 public class SessionManagerImpl implements SessionManager<Session> {
33
34
35 private final Logger log = LoggerFactory.getLogger(SessionManagerImpl.class);
36
37
38 private final int sessionIDSize = 32;
39
40
41 private final SecureRandom prng = new SecureRandom();
42
43
44 private StorageService<String, SessionManagerEntry> sessionStore;
45
46
47 private String partition;
48
49
50 private long sessionLifetime;
51
52
53
54
55
56
57
58 public SessionManagerImpl(StorageService<String, SessionManagerEntry> storageService, long lifetime) {
59 sessionStore = storageService;
60 partition = "session";
61 sessionLifetime = lifetime;
62 }
63
64
65
66
67
68
69
70
71 public SessionManagerImpl(StorageService<String, SessionManagerEntry> storageService, String storageParition,
72 long lifetime) {
73 sessionStore = storageService;
74 if (!DatatypeHelper.isEmpty(storageParition)) {
75 partition = DatatypeHelper.safeTrim(storageParition);
76 } else {
77 partition = "session";
78 }
79 sessionLifetime = lifetime;
80 }
81
82
83 public Session createSession() {
84
85 byte[] sid = new byte[sessionIDSize];
86 prng.nextBytes(sid);
87 String sessionID = Hex.encode(sid);
88
89 byte[] sessionSecret = new byte[16];
90 prng.nextBytes(sessionSecret);
91
92 Session session = new SessionImpl(sessionID, sessionSecret, sessionLifetime);
93 SessionManagerEntry sessionEntry = new SessionManagerEntry(session, sessionLifetime);
94 sessionStore.put(partition, sessionID, sessionEntry);
95
96 MDC.put("idpSessionId", sessionID);
97 log.trace("Created session {}", sessionID);
98 return session;
99 }
100
101
102 public Session createSession(String principal) {
103
104 byte[] sid = new byte[sessionIDSize];
105 prng.nextBytes(sid);
106 String sessionID = Hex.encode(sid);
107
108 byte[] sessionSecret = new byte[16];
109 prng.nextBytes(sessionSecret);
110
111 Session session = new SessionImpl(sessionID, sessionSecret, sessionLifetime);
112 SessionManagerEntry sessionEntry = new SessionManagerEntry(session, sessionLifetime);
113 sessionStore.put(partition, sessionID, sessionEntry);
114
115 MDC.put("idpSessionId", sessionID);
116 log.trace("Created session {}", sessionID);
117 return session;
118 }
119
120
121 public void destroySession(String sessionID) {
122 if (sessionID == null) {
123 return;
124 }
125
126 SessionManagerEntry sessionEntry = sessionStore.get(partition, sessionID);
127 if (sessionEntry == null) {
128 return;
129 }
130 for(String sessionIndex : sessionEntry.getSessionIndexes()){
131 sessionStore.remove(partition, sessionIndex);
132 }
133 sessionStore.remove(partition, sessionID);
134 }
135
136
137 public Session getSession(String sessionID) {
138 if (sessionID == null) {
139 return null;
140 }
141
142 SessionManagerEntry sessionEntry = sessionStore.get(partition, sessionID);
143 if (sessionEntry == null) {
144 return null;
145 }
146
147 if (sessionEntry.isExpired()) {
148 destroySession(sessionEntry.getSessionId());
149 return null;
150 } else {
151 return sessionEntry.getSession();
152 }
153 }
154
155
156 public boolean indexSession(Session session, String index) {
157 if (sessionStore.contains(partition, index)) {
158 return false;
159 }
160
161 SessionManagerEntry sessionEntry = sessionStore.get(partition, session.getSessionID());
162 if (sessionEntry == null) {
163 return false;
164 }
165
166 if (sessionEntry.getSessionIndexes().contains(index)) {
167 return true;
168 }
169
170 sessionEntry.getSessionIndexes().add(index);
171 sessionStore.put(partition, index, sessionEntry);
172 log.trace("Added index {} to session {}", index, session.getSessionID());
173 return true;
174 }
175
176
177 public void removeSessionIndex(String index) {
178 SessionManagerEntry sessionEntry = sessionStore.remove(partition, index);
179 if (sessionEntry != null) {
180 log.trace("Removing index {} for session {}", index, sessionEntry.getSessionId());
181 sessionEntry.getSessionIndexes().remove(index);
182 }
183 }
184 }