SessionManager and UI Fix
This commit is contained in:
@@ -17,8 +17,7 @@
|
||||
|
||||
package org.maxkey.authn.session;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalTime;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -43,6 +42,7 @@ public class InMemorySessionManager implements SessionManager{
|
||||
|
||||
public InMemorySessionManager(int validitySeconds) {
|
||||
super();
|
||||
this.validitySeconds = validitySeconds;
|
||||
sessionStore =
|
||||
Caffeine.newBuilder()
|
||||
.expireAfterWrite(validitySeconds, TimeUnit.SECONDS)
|
||||
@@ -53,6 +53,7 @@ public class InMemorySessionManager implements SessionManager{
|
||||
|
||||
@Override
|
||||
public void create(String sessionId, Session session) {
|
||||
session.setExpiredTime(session.getLastAccessTime().plusSeconds(validitySeconds));
|
||||
sessionStore.put(sessionId, session);
|
||||
}
|
||||
|
||||
@@ -70,10 +71,15 @@ public class InMemorySessionManager implements SessionManager{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session refresh(String sessionId,LocalTime refreshTime) {
|
||||
public Session refresh(String sessionId,LocalDateTime refreshTime) {
|
||||
Session session = get(sessionId);
|
||||
session.setLastAccessTime(refreshTime);
|
||||
create(sessionId , session);
|
||||
if(session != null) {
|
||||
_logger.debug("refresh session Id {} at refreshTime {}",sessionId,refreshTime);
|
||||
session.setLastAccessTime(refreshTime);
|
||||
//invalidate sessionId then renew one
|
||||
sessionStore.invalidate(sessionId);
|
||||
create(sessionId , session);
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
@@ -81,18 +87,21 @@ public class InMemorySessionManager implements SessionManager{
|
||||
public Session refresh(String sessionId) {
|
||||
Session session = get(sessionId);
|
||||
|
||||
LocalTime currentTime = LocalTime.now();
|
||||
Duration duration = Duration.between(currentTime, session.getLastAccessTime());
|
||||
|
||||
_logger.trace("Session duration " + duration.getSeconds());
|
||||
|
||||
if(duration.getSeconds() > Session.MAX_EXPIRY_DURATION) {
|
||||
if(session != null) {
|
||||
LocalDateTime currentTime = LocalDateTime.now();
|
||||
_logger.debug("refresh session Id {} at time {}",sessionId,currentTime);
|
||||
session.setLastAccessTime(currentTime);
|
||||
return refresh(sessionId,currentTime);
|
||||
//invalidate sessionId then renew one
|
||||
sessionStore.invalidate(sessionId);
|
||||
create(sessionId , session);
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
public int getValiditySeconds() {
|
||||
return validitySeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HistoryLogin> querySessions() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
|
||||
package org.maxkey.authn.session;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalTime;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import org.maxkey.entity.HistoryLogin;
|
||||
@@ -65,6 +64,7 @@ public class RedisSessionManager implements SessionManager {
|
||||
|
||||
@Override
|
||||
public void create(String sessionId, Session session) {
|
||||
session.setExpiredTime(session.getLastAccessTime().plusSeconds(validitySeconds));
|
||||
RedisConnection conn = connectionFactory.getConnection();
|
||||
conn.setexObject( getKey(sessionId), validitySeconds, session);
|
||||
conn.close();
|
||||
@@ -97,25 +97,24 @@ public class RedisSessionManager implements SessionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session refresh(String sessionId,LocalTime refreshTime) {
|
||||
public Session refresh(String sessionId,LocalDateTime refreshTime) {
|
||||
Session session = get(sessionId);
|
||||
session.setLastAccessTime(refreshTime);
|
||||
create(sessionId , session);
|
||||
if(session != null) {
|
||||
_logger.debug("refresh session Id {} at {}",sessionId,refreshTime);
|
||||
session.setLastAccessTime(refreshTime);
|
||||
create(sessionId , session);
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session refresh(String sessionId) {
|
||||
Session session = get(sessionId);
|
||||
|
||||
LocalTime currentTime = LocalTime.now();
|
||||
Duration duration = Duration.between(currentTime, session.getLastAccessTime());
|
||||
|
||||
_logger.trace("Session duration " + duration.getSeconds());
|
||||
|
||||
if(duration.getSeconds() > Session.MAX_EXPIRY_DURATION) {
|
||||
if(session != null) {
|
||||
LocalDateTime currentTime = LocalDateTime.now();
|
||||
_logger.debug("refresh session Id {} at time {}",sessionId,currentTime);
|
||||
session.setLastAccessTime(currentTime);
|
||||
return refresh(sessionId,currentTime);
|
||||
create(sessionId , session);
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package org.maxkey.authn.session;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalTime;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.maxkey.entity.apps.Apps;
|
||||
@@ -34,9 +34,11 @@ public class Session implements Serializable{
|
||||
|
||||
public String id;
|
||||
|
||||
public LocalTime startTimestamp;
|
||||
public LocalDateTime startTimestamp;
|
||||
|
||||
public LocalTime lastAccessTime;
|
||||
public LocalDateTime lastAccessTime;
|
||||
|
||||
public LocalDateTime expiredTime;
|
||||
|
||||
public Authentication authentication;
|
||||
|
||||
@@ -45,23 +47,23 @@ public class Session implements Serializable{
|
||||
public Session() {
|
||||
super();
|
||||
this.id = WebContext.genId();;
|
||||
this.startTimestamp = LocalTime.now();
|
||||
this.lastAccessTime = LocalTime.now();
|
||||
this.startTimestamp = LocalDateTime.now();
|
||||
this.lastAccessTime = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public Session(String sessionId) {
|
||||
super();
|
||||
this.id = sessionId;
|
||||
this.startTimestamp = LocalTime.now();
|
||||
this.lastAccessTime = LocalTime.now();
|
||||
this.startTimestamp = LocalDateTime.now();
|
||||
this.lastAccessTime = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public Session(String sessionId,Authentication authentication) {
|
||||
super();
|
||||
this.id = sessionId;
|
||||
this.authentication = authentication;
|
||||
this.startTimestamp = LocalTime.now();
|
||||
this.lastAccessTime = LocalTime.now();
|
||||
this.startTimestamp = LocalDateTime.now();
|
||||
this.lastAccessTime = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
@@ -77,22 +79,30 @@ public class Session implements Serializable{
|
||||
}
|
||||
|
||||
|
||||
public LocalTime getStartTimestamp() {
|
||||
public LocalDateTime getStartTimestamp() {
|
||||
return startTimestamp;
|
||||
}
|
||||
|
||||
public void setStartTimestamp(LocalTime startTimestamp) {
|
||||
public void setStartTimestamp(LocalDateTime startTimestamp) {
|
||||
this.startTimestamp = startTimestamp;
|
||||
}
|
||||
|
||||
public LocalTime getLastAccessTime() {
|
||||
public LocalDateTime getLastAccessTime() {
|
||||
return lastAccessTime;
|
||||
}
|
||||
|
||||
public void setLastAccessTime(LocalTime lastAccessTime) {
|
||||
public void setLastAccessTime(LocalDateTime lastAccessTime) {
|
||||
this.lastAccessTime = lastAccessTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getExpiredTime() {
|
||||
return expiredTime;
|
||||
}
|
||||
|
||||
public void setExpiredTime(LocalDateTime expiredTime) {
|
||||
this.expiredTime = expiredTime;
|
||||
}
|
||||
|
||||
public Authentication getAuthentication() {
|
||||
return authentication;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
package org.maxkey.authn.session;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import org.maxkey.entity.HistoryLogin;
|
||||
@@ -30,11 +30,13 @@ public interface SessionManager {
|
||||
|
||||
public Session get(String sessionId);
|
||||
|
||||
public Session refresh(String sessionId ,LocalTime refreshTime);
|
||||
public Session refresh(String sessionId ,LocalDateTime refreshTime);
|
||||
|
||||
public Session refresh(String sessionId);
|
||||
|
||||
public List<HistoryLogin> querySessions();
|
||||
|
||||
public int getValiditySeconds();
|
||||
|
||||
public void terminate(String sessionId,String userId,String username);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ package org.maxkey.authn.session;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalTime;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@@ -34,6 +34,14 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
/**
|
||||
* SessionManager
|
||||
* Level 1 in memory,store in Caffeine
|
||||
* Level 2 in Redis
|
||||
* user session status in database
|
||||
* @author shimh
|
||||
*
|
||||
*/
|
||||
public class SessionManagerFactory implements SessionManager{
|
||||
private static final Logger _logger =
|
||||
LoggerFactory.getLogger(SessionManagerFactory.class);
|
||||
@@ -53,12 +61,15 @@ public class SessionManagerFactory implements SessionManager{
|
||||
|
||||
private RedisSessionManager redisSessionManager;
|
||||
|
||||
private boolean isRedis = false;
|
||||
private boolean isRedis = false;
|
||||
|
||||
private int validitySeconds ;
|
||||
|
||||
public SessionManagerFactory(int persistence,
|
||||
JdbcTemplate jdbcTemplate,
|
||||
RedisConnectionFactory redisConnFactory,
|
||||
int validitySeconds) {
|
||||
this.validitySeconds = validitySeconds;
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
this.inMemorySessionManager =
|
||||
new InMemorySessionManager(validitySeconds);
|
||||
@@ -94,11 +105,12 @@ public class SessionManagerFactory implements SessionManager{
|
||||
return session;
|
||||
}
|
||||
|
||||
public Session refresh(String sessionId, LocalTime refreshTime) {
|
||||
public Session refresh(String sessionId, LocalDateTime refreshTime) {
|
||||
Session session = null;
|
||||
if(isRedis) {
|
||||
session = redisSessionManager.refresh(sessionId,refreshTime);
|
||||
//renew one
|
||||
inMemorySessionManager.remove(sessionId);
|
||||
inMemorySessionManager.create(sessionId, session);
|
||||
}else {
|
||||
session = inMemorySessionManager.refresh(sessionId,refreshTime);
|
||||
@@ -111,6 +123,7 @@ public class SessionManagerFactory implements SessionManager{
|
||||
if(isRedis) {
|
||||
session = redisSessionManager.refresh(sessionId);
|
||||
//renew one
|
||||
inMemorySessionManager.remove(sessionId);
|
||||
inMemorySessionManager.create(sessionId, session);
|
||||
}else {
|
||||
session = inMemorySessionManager.refresh(sessionId);
|
||||
@@ -142,12 +155,16 @@ public class SessionManagerFactory implements SessionManager{
|
||||
|
||||
public void terminate(String sessionId, String userId, String username) {
|
||||
String lastLogoffTime = DateUtils.formatDateTime(new Date());
|
||||
_logger.trace("{} user {} terminate Ticket {} ." ,lastLogoffTime,username, sessionId);
|
||||
_logger.trace("{} user {} terminate session {} ." ,lastLogoffTime,username, sessionId);
|
||||
this.profileLastLogoffTime(userId, lastLogoffTime);
|
||||
this.sessionLogoff(sessionId, lastLogoffTime);
|
||||
this.remove(sessionId);
|
||||
}
|
||||
|
||||
public int getValiditySeconds() {
|
||||
return validitySeconds;
|
||||
}
|
||||
|
||||
private final class OnlineTicketRowMapper implements RowMapper<HistoryLogin> {
|
||||
@Override
|
||||
public HistoryLogin mapRow(ResultSet rs, int rowNum)
|
||||
|
||||
@@ -35,8 +35,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(value = "/auth")
|
||||
public class LoginRefreshPoint {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(LoginRefreshPoint.class);
|
||||
public class LoginTokenRefreshPoint {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(LoginTokenRefreshPoint.class);
|
||||
|
||||
@Autowired
|
||||
AuthTokenService authTokenService;
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.authn.web;
|
||||
@@ -202,7 +202,7 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
|
||||
RedisConnectionFactory redisConnFactory,
|
||||
@Value("${maxkey.session.timeout:1800}") int timeout
|
||||
) {
|
||||
_logger.trace("session timeout " + timeout);
|
||||
_logger.debug("session timeout " + timeout);
|
||||
SessionManager sessionManager =
|
||||
new SessionManagerFactory(
|
||||
persistence, jdbcTemplate, redisConnFactory,timeout);
|
||||
|
||||
Reference in New Issue
Block a user