mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-07 17:38:32 +08:00
#IAZNZS oauth2单点注销没有生效修复
This commit is contained in:
parent
c2628b271a
commit
4ceaebf80c
@ -20,8 +20,8 @@ package org.dromara.maxkey.authn.session;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.dromara.maxkey.entity.apps.Apps;
|
|
||||||
import org.dromara.maxkey.web.WebContext;
|
import org.dromara.maxkey.web.WebContext;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ public class Session implements Serializable{
|
|||||||
|
|
||||||
public Authentication authentication;
|
public Authentication authentication;
|
||||||
|
|
||||||
private HashMap<String , Apps> authorizedApps = new HashMap<String , Apps>();
|
Map<String , VisitedDto> visited = new HashMap<>();
|
||||||
|
|
||||||
public Session() {
|
public Session() {
|
||||||
super();
|
super();
|
||||||
@ -105,19 +105,19 @@ public class Session implements Serializable{
|
|||||||
this.authentication = authentication;
|
this.authentication = authentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<String, Apps> getAuthorizedApps() {
|
public void visited(VisitedDto visited) {
|
||||||
return authorizedApps;
|
this.visited.put(visited.getAppId(), visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthorizedApps(HashMap<String, Apps> authorizedApps) {
|
public Map<String, VisitedDto> getVisited() {
|
||||||
this.authorizedApps = authorizedApps;
|
return visited;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthorizedApp(Apps authorizedApp) {
|
|
||||||
this.authorizedApps.put(authorizedApp.getId(), authorizedApp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public void setVisited(Map<String, VisitedDto> visited) {
|
||||||
|
this.visited = visited;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("Session [id=");
|
builder.append("Session [id=");
|
||||||
|
|||||||
@ -39,4 +39,6 @@ public interface SessionManager {
|
|||||||
public int getValiditySeconds();
|
public int getValiditySeconds();
|
||||||
|
|
||||||
public void terminate(String sessionId,String userId,String username);
|
public void terminate(String sessionId,String userId,String username);
|
||||||
|
|
||||||
|
public void visited(String sessionId , VisitedDto visited);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2024] [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.dromara.maxkey.authn.session;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.dromara.maxkey.entity.apps.Apps;
|
||||||
|
import org.dromara.maxkey.entity.apps.AppsCasDetails;
|
||||||
|
|
||||||
|
public class VisitedDto implements Serializable{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -6694914707659511202L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* appId or client id
|
||||||
|
*/
|
||||||
|
String appId;
|
||||||
|
/**
|
||||||
|
* protocol
|
||||||
|
*/
|
||||||
|
String protocol;
|
||||||
|
/**
|
||||||
|
* ticket
|
||||||
|
*/
|
||||||
|
String ticket;
|
||||||
|
/**
|
||||||
|
* token
|
||||||
|
*/
|
||||||
|
String token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* refreshToken
|
||||||
|
*/
|
||||||
|
String refreshToken;
|
||||||
|
/**
|
||||||
|
* logoutType
|
||||||
|
*/
|
||||||
|
int logoutType;
|
||||||
|
/**
|
||||||
|
* logoutUrl
|
||||||
|
*/
|
||||||
|
String logoutUrl;
|
||||||
|
|
||||||
|
|
||||||
|
public VisitedDto(AppsCasDetails app,String ticket ) {
|
||||||
|
this.appId = app.getId();
|
||||||
|
this.protocol = app.getProtocol();
|
||||||
|
this.logoutType = app.getLogoutType();
|
||||||
|
this.logoutUrl = app.getLogoutUrl();
|
||||||
|
this.ticket = ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VisitedDto(Apps app,String ticket ) {
|
||||||
|
this.appId = app.getId();
|
||||||
|
this.protocol = app.getProtocol();
|
||||||
|
this.logoutType = app.getLogoutType();
|
||||||
|
this.logoutUrl = app.getLogoutUrl();
|
||||||
|
this.ticket = ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppId() {
|
||||||
|
return appId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppId(String appId) {
|
||||||
|
this.appId = appId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProtocol() {
|
||||||
|
return protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProtocol(String protocol) {
|
||||||
|
this.protocol = protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTicket() {
|
||||||
|
return ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTicket(String ticket) {
|
||||||
|
this.ticket = ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRefreshToken() {
|
||||||
|
return refreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRefreshToken(String refreshToken) {
|
||||||
|
this.refreshToken = refreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLogoutType() {
|
||||||
|
return logoutType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogoutType(int logoutType) {
|
||||||
|
this.logoutType = logoutType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLogoutUrl() {
|
||||||
|
return logoutUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogoutUrl(String logoutUrl) {
|
||||||
|
this.logoutUrl = logoutUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("VisitedDto [appId=");
|
||||||
|
builder.append(appId);
|
||||||
|
builder.append(", protocol=");
|
||||||
|
builder.append(protocol);
|
||||||
|
builder.append(", ticket=");
|
||||||
|
builder.append(ticket);
|
||||||
|
builder.append(", token=");
|
||||||
|
builder.append(token);
|
||||||
|
builder.append(", refreshToken=");
|
||||||
|
builder.append(refreshToken);
|
||||||
|
builder.append(", logoutType=");
|
||||||
|
builder.append(logoutType);
|
||||||
|
builder.append(", logoutUrl=");
|
||||||
|
builder.append(logoutUrl);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -15,12 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.dromara.maxkey.authn.session;
|
package org.dromara.maxkey.authn.session.impl;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.dromara.maxkey.authn.session.Session;
|
||||||
|
import org.dromara.maxkey.authn.session.SessionManager;
|
||||||
|
import org.dromara.maxkey.authn.session.VisitedDto;
|
||||||
import org.dromara.maxkey.entity.history.HistoryLogin;
|
import org.dromara.maxkey.entity.history.HistoryLogin;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -113,4 +116,14 @@ public class InMemorySessionManager implements SessionManager{
|
|||||||
// not need implement
|
// not need implement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visited(String sessionId, VisitedDto visited) {
|
||||||
|
Session session = this.get(sessionId);
|
||||||
|
//set token or ticket to Visited , bind user session
|
||||||
|
session.visited(visited);
|
||||||
|
//override the session
|
||||||
|
this.create(sessionId, session);
|
||||||
|
_logger.debug("session {} store visited {} ." , sessionId , visited);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -15,11 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.dromara.maxkey.authn.session;
|
package org.dromara.maxkey.authn.session.impl;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dromara.maxkey.authn.session.Session;
|
||||||
|
import org.dromara.maxkey.authn.session.SessionManager;
|
||||||
|
import org.dromara.maxkey.authn.session.VisitedDto;
|
||||||
import org.dromara.maxkey.entity.history.HistoryLogin;
|
import org.dromara.maxkey.entity.history.HistoryLogin;
|
||||||
import org.dromara.maxkey.persistence.redis.RedisConnection;
|
import org.dromara.maxkey.persistence.redis.RedisConnection;
|
||||||
import org.dromara.maxkey.persistence.redis.RedisConnectionFactory;
|
import org.dromara.maxkey.persistence.redis.RedisConnectionFactory;
|
||||||
@ -135,5 +138,15 @@ public class RedisSessionManager implements SessionManager {
|
|||||||
// not need implement
|
// not need implement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visited(String sessionId, VisitedDto visited) {
|
||||||
|
Session session = this.get(sessionId);
|
||||||
|
//set token or ticket to Visited , bind user session
|
||||||
|
session.visited(visited);
|
||||||
|
//override the session
|
||||||
|
this.create(sessionId, session);
|
||||||
|
_logger.debug("session {} store visited {} ." , sessionId , visited);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.dromara.maxkey.authn.session;
|
package org.dromara.maxkey.authn.session.impl;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@ -24,6 +24,9 @@ import java.time.LocalDateTime;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dromara.maxkey.authn.session.Session;
|
||||||
|
import org.dromara.maxkey.authn.session.SessionManager;
|
||||||
|
import org.dromara.maxkey.authn.session.VisitedDto;
|
||||||
import org.dromara.maxkey.constants.ConstsPersistence;
|
import org.dromara.maxkey.constants.ConstsPersistence;
|
||||||
import org.dromara.maxkey.entity.history.HistoryLogin;
|
import org.dromara.maxkey.entity.history.HistoryLogin;
|
||||||
import org.dromara.maxkey.entity.idm.UserInfo;
|
import org.dromara.maxkey.entity.idm.UserInfo;
|
||||||
@ -42,9 +45,9 @@ import org.springframework.jdbc.core.RowMapper;
|
|||||||
* @author shimh
|
* @author shimh
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SessionManagerFactory implements SessionManager{
|
public class SessionManagerImpl implements SessionManager{
|
||||||
private static final Logger _logger =
|
private static final Logger _logger =
|
||||||
LoggerFactory.getLogger(SessionManagerFactory.class);
|
LoggerFactory.getLogger(SessionManagerImpl.class);
|
||||||
|
|
||||||
private static final String DEFAULT_DEFAULT_SELECT_STATEMENT =
|
private static final String DEFAULT_DEFAULT_SELECT_STATEMENT =
|
||||||
"select id,sessionid,userId,username,displayname,logintime from mxk_history_login where sessionstatus = 1";
|
"select id,sessionid,userId,username,displayname,logintime from mxk_history_login where sessionstatus = 1";
|
||||||
@ -68,7 +71,7 @@ public class SessionManagerFactory implements SessionManager{
|
|||||||
|
|
||||||
private int validitySeconds ;
|
private int validitySeconds ;
|
||||||
|
|
||||||
public SessionManagerFactory(int persistence,
|
public SessionManagerImpl(int persistence,
|
||||||
JdbcTemplate jdbcTemplate,
|
JdbcTemplate jdbcTemplate,
|
||||||
RedisConnectionFactory redisConnFactory,
|
RedisConnectionFactory redisConnFactory,
|
||||||
int validitySeconds) {
|
int validitySeconds) {
|
||||||
@ -192,4 +195,13 @@ public class SessionManagerFactory implements SessionManager{
|
|||||||
return history;
|
return history;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visited(String sessionId, VisitedDto visited) {
|
||||||
|
if(isRedis) {
|
||||||
|
redisSessionManager.visited(sessionId,visited);
|
||||||
|
}else {
|
||||||
|
inMemorySessionManager.visited(sessionId,visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@
|
|||||||
package org.dromara.maxkey.autoconfigure;
|
package org.dromara.maxkey.autoconfigure;
|
||||||
|
|
||||||
import org.dromara.maxkey.authn.session.SessionManager;
|
import org.dromara.maxkey.authn.session.SessionManager;
|
||||||
import org.dromara.maxkey.authn.session.SessionManagerFactory;
|
import org.dromara.maxkey.authn.session.impl.SessionManagerImpl;
|
||||||
import org.dromara.maxkey.authn.web.HttpSessionListenerAdapter;
|
import org.dromara.maxkey.authn.web.HttpSessionListenerAdapter;
|
||||||
import org.dromara.maxkey.authn.web.SavedRequestAwareAuthenticationSuccessHandler;
|
import org.dromara.maxkey.authn.web.SavedRequestAwareAuthenticationSuccessHandler;
|
||||||
import org.dromara.maxkey.persistence.redis.RedisConnectionFactory;
|
import org.dromara.maxkey.persistence.redis.RedisConnectionFactory;
|
||||||
@ -50,7 +50,7 @@ public class SessionAutoConfiguration {
|
|||||||
@Value("${maxkey.auth.session.timeout:1800}") int timeout
|
@Value("${maxkey.auth.session.timeout:1800}") int timeout
|
||||||
) {
|
) {
|
||||||
_logger.debug("session timeout {}" , timeout);
|
_logger.debug("session timeout {}" , timeout);
|
||||||
return new SessionManagerFactory(
|
return new SessionManagerImpl(
|
||||||
persistence, jdbcTemplate, redisConnFactory,timeout);
|
persistence, jdbcTemplate, redisConnFactory,timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -170,8 +170,6 @@ public class Apps extends JpaEntity implements Serializable {
|
|||||||
private String instName;
|
private String instName;
|
||||||
|
|
||||||
protected String loginDateTime;
|
protected String loginDateTime;
|
||||||
|
|
||||||
protected String onlineTicket;
|
|
||||||
|
|
||||||
public Apps() {
|
public Apps() {
|
||||||
super();
|
super();
|
||||||
@ -600,14 +598,6 @@ public class Apps extends JpaEntity implements Serializable {
|
|||||||
this.loginDateTime = loginDateTime;
|
this.loginDateTime = loginDateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOnlineTicket() {
|
|
||||||
return onlineTicket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnlineTicket(String onlineTicket) {
|
|
||||||
this.onlineTicket = onlineTicket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAdapterId() {
|
public String getAdapterId() {
|
||||||
return adapterId;
|
return adapterId;
|
||||||
}
|
}
|
||||||
@ -713,8 +703,6 @@ public class Apps extends JpaEntity implements Serializable {
|
|||||||
builder.append(description);
|
builder.append(description);
|
||||||
builder.append(", loginDateTime=");
|
builder.append(", loginDateTime=");
|
||||||
builder.append(loginDateTime);
|
builder.append(loginDateTime);
|
||||||
builder.append(", onlineTicket=");
|
|
||||||
builder.append(onlineTicket);
|
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,22 +20,21 @@ package org.dromara.maxkey.authz.singlelogout;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.dromara.maxkey.authn.SignPrincipal;
|
import org.dromara.maxkey.authn.session.VisitedDto;
|
||||||
import org.dromara.maxkey.entity.apps.Apps;
|
|
||||||
import org.dromara.maxkey.util.DateUtils;
|
import org.dromara.maxkey.util.DateUtils;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
public class DefaultSingleLogout extends SingleLogout{
|
public class DefaultSingleLogout extends SingleLogout{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendRequest(Authentication authentication,Apps logoutApp) {
|
public void sendRequest(Authentication authentication,VisitedDto visited) {
|
||||||
HashMap<String,Object> logoutParameters = new HashMap<String,Object>();
|
HashMap<String,Object> logoutParameters = new HashMap<String,Object>();
|
||||||
logoutParameters.put("id", UUID.randomUUID().toString());
|
logoutParameters.put("id", UUID.randomUUID().toString());
|
||||||
logoutParameters.put("principal", authentication.getName());
|
logoutParameters.put("principal", authentication.getName());
|
||||||
logoutParameters.put("request", "logoutRequest");
|
logoutParameters.put("request", "logoutRequest");
|
||||||
logoutParameters.put("issueInstant", DateUtils.getCurrentDateAsString(DateUtils.FORMAT_DATE_ISO_TIMESTAMP));
|
logoutParameters.put("issueInstant", DateUtils.getCurrentDateAsString(DateUtils.FORMAT_DATE_ISO_TIMESTAMP));
|
||||||
logoutParameters.put("ticket", ((SignPrincipal)authentication.getPrincipal()).getSessionId());
|
logoutParameters.put("ticket", visited.getTicket());
|
||||||
postMessage(logoutApp.getLogoutUrl(),logoutParameters);
|
postMessage(visited.getLogoutUrl(),logoutParameters);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ package org.dromara.maxkey.authz.singlelogout;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.dromara.maxkey.entity.apps.Apps;
|
import org.dromara.maxkey.authn.session.VisitedDto;
|
||||||
import org.dromara.maxkey.util.DateUtils;
|
import org.dromara.maxkey.util.DateUtils;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
@ -43,17 +43,17 @@ public class SamlSingleLogout extends SingleLogout{
|
|||||||
+ "</saml:NameID><samlp:SessionIndex>%s</samlp:SessionIndex></samlp:LogoutRequest>";
|
+ "</saml:NameID><samlp:SessionIndex>%s</samlp:SessionIndex></samlp:LogoutRequest>";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendRequest(Authentication authentication,Apps logoutApp) {
|
public void sendRequest(Authentication authentication,VisitedDto visited) {
|
||||||
String requestMessage = String.format(logoutRequestMessage,
|
String requestMessage = String.format(logoutRequestMessage,
|
||||||
UUID.randomUUID().toString(),
|
UUID.randomUUID().toString(),
|
||||||
DateUtils.getCurrentDateAsString(DateUtils.FORMAT_DATE_ISO_TIMESTAMP),
|
DateUtils.getCurrentDateAsString(DateUtils.FORMAT_DATE_ISO_TIMESTAMP),
|
||||||
authentication.getName(),
|
authentication.getName(),
|
||||||
logoutApp.getOnlineTicket()
|
visited.getTicket()
|
||||||
);
|
);
|
||||||
|
|
||||||
HashMap<String,Object> logoutParameters = new HashMap<String,Object>();
|
HashMap<String,Object> logoutParameters = new HashMap<String,Object>();
|
||||||
logoutParameters.put(LOGOUT_REQUEST_PARAMETER, requestMessage);
|
logoutParameters.put(LOGOUT_REQUEST_PARAMETER, requestMessage);
|
||||||
postMessage(logoutApp.getLogoutUrl(),logoutParameters);
|
postMessage(visited.getLogoutUrl(),logoutParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SamlSingleLogout() {
|
public SamlSingleLogout() {
|
||||||
|
|||||||
@ -19,7 +19,7 @@ package org.dromara.maxkey.authz.singlelogout;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.dromara.maxkey.entity.apps.Apps;
|
import org.dromara.maxkey.authn.session.VisitedDto;
|
||||||
import org.dromara.maxkey.web.HttpRequestAdapter;
|
import org.dromara.maxkey.web.HttpRequestAdapter;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -28,7 +28,7 @@ import org.springframework.security.core.Authentication;
|
|||||||
public abstract class SingleLogout {
|
public abstract class SingleLogout {
|
||||||
private static final Logger _logger = LoggerFactory.getLogger(SingleLogout.class);
|
private static final Logger _logger = LoggerFactory.getLogger(SingleLogout.class);
|
||||||
|
|
||||||
public abstract void sendRequest(Authentication authentication,Apps logoutApp) ;
|
public abstract void sendRequest(Authentication authentication,VisitedDto visited) ;
|
||||||
|
|
||||||
public void postMessage(String url,Map<String, Object> paramMap) {
|
public void postMessage(String url,Map<String, Object> paramMap) {
|
||||||
_logger.debug("post logout message to url {}" , url);
|
_logger.debug("post logout message to url {}" , url);
|
||||||
|
|||||||
@ -24,7 +24,7 @@ import java.security.Principal;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.dromara.maxkey.authn.session.Session;
|
import org.dromara.maxkey.authn.session.VisitedDto;
|
||||||
import org.dromara.maxkey.authn.web.AuthorizationUtils;
|
import org.dromara.maxkey.authn.web.AuthorizationUtils;
|
||||||
import org.dromara.maxkey.authz.cas.endpoint.ticket.CasConstants;
|
import org.dromara.maxkey.authz.cas.endpoint.ticket.CasConstants;
|
||||||
import org.dromara.maxkey.authz.cas.endpoint.ticket.ServiceTicketImpl;
|
import org.dromara.maxkey.authz.cas.endpoint.ticket.ServiceTicketImpl;
|
||||||
@ -155,15 +155,9 @@ public class CasAuthorizeEndpoint extends CasBaseAuthorizeEndpoint{
|
|||||||
if(casDetails.getLogoutType()==LogoutType.BACK_CHANNEL) {
|
if(casDetails.getLogoutType()==LogoutType.BACK_CHANNEL) {
|
||||||
_logger.debug("CAS LogoutType BACK_CHANNEL ... ");
|
_logger.debug("CAS LogoutType BACK_CHANNEL ... ");
|
||||||
String sessionId = AuthorizationUtils.getPrincipal().getSessionId();
|
String sessionId = AuthorizationUtils.getPrincipal().getSessionId();
|
||||||
_logger.trace("get session by id {} . ",sessionId);
|
VisitedDto visited = new VisitedDto(casDetails,ticket);
|
||||||
Session session = sessionManager.get(sessionId);
|
sessionManager.visited(sessionId, visited);
|
||||||
_logger.trace("current session {} ",session);
|
_logger.debug("App id {} , name {} , CAS LogoutType BACK_CHANNEL ... " , casDetails.getId(),casDetails.getAppName());
|
||||||
//set cas ticket as OnlineTicketId
|
|
||||||
casDetails.setOnlineTicket(ticket);
|
|
||||||
session.setAuthorizedApp(casDetails);
|
|
||||||
_logger.trace("session store ticket {} .",ticket);
|
|
||||||
sessionManager.create(sessionId, session);
|
|
||||||
_logger.debug("CAS LogoutType session store ticket to AuthorizedApp .");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.debug("redirect to CAS Client URL {}" , callbackUrl);
|
_logger.debug("redirect to CAS Client URL {}" , callbackUrl);
|
||||||
|
|||||||
@ -17,11 +17,15 @@ import java.util.Date;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.dromara.maxkey.authn.SignPrincipal;
|
||||||
|
import org.dromara.maxkey.authn.session.SessionManager;
|
||||||
|
import org.dromara.maxkey.authn.session.VisitedDto;
|
||||||
import org.dromara.maxkey.authz.oauth2.common.DefaultExpiringOAuth2RefreshToken;
|
import org.dromara.maxkey.authz.oauth2.common.DefaultExpiringOAuth2RefreshToken;
|
||||||
import org.dromara.maxkey.authz.oauth2.common.DefaultOAuth2AccessToken;
|
import org.dromara.maxkey.authz.oauth2.common.DefaultOAuth2AccessToken;
|
||||||
import org.dromara.maxkey.authz.oauth2.common.DefaultOAuth2RefreshToken;
|
import org.dromara.maxkey.authz.oauth2.common.DefaultOAuth2RefreshToken;
|
||||||
import org.dromara.maxkey.authz.oauth2.common.ExpiringOAuth2RefreshToken;
|
import org.dromara.maxkey.authz.oauth2.common.ExpiringOAuth2RefreshToken;
|
||||||
import org.dromara.maxkey.authz.oauth2.common.OAuth2AccessToken;
|
import org.dromara.maxkey.authz.oauth2.common.OAuth2AccessToken;
|
||||||
|
import org.dromara.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||||
import org.dromara.maxkey.authz.oauth2.common.OAuth2RefreshToken;
|
import org.dromara.maxkey.authz.oauth2.common.OAuth2RefreshToken;
|
||||||
import org.dromara.maxkey.authz.oauth2.common.exceptions.InvalidGrantException;
|
import org.dromara.maxkey.authz.oauth2.common.exceptions.InvalidGrantException;
|
||||||
import org.dromara.maxkey.authz.oauth2.common.exceptions.InvalidScopeException;
|
import org.dromara.maxkey.authz.oauth2.common.exceptions.InvalidScopeException;
|
||||||
@ -31,7 +35,11 @@ import org.dromara.maxkey.authz.oauth2.provider.ClientRegistrationException;
|
|||||||
import org.dromara.maxkey.authz.oauth2.provider.OAuth2Authentication;
|
import org.dromara.maxkey.authz.oauth2.provider.OAuth2Authentication;
|
||||||
import org.dromara.maxkey.authz.oauth2.provider.OAuth2Request;
|
import org.dromara.maxkey.authz.oauth2.provider.OAuth2Request;
|
||||||
import org.dromara.maxkey.authz.oauth2.provider.TokenRequest;
|
import org.dromara.maxkey.authz.oauth2.provider.TokenRequest;
|
||||||
|
import org.dromara.maxkey.entity.apps.Apps;
|
||||||
import org.dromara.maxkey.entity.apps.oauth2.provider.ClientDetails;
|
import org.dromara.maxkey.entity.apps.oauth2.provider.ClientDetails;
|
||||||
|
import org.dromara.maxkey.persistence.service.AppsService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
@ -54,6 +62,7 @@ import org.springframework.util.Assert;
|
|||||||
*/
|
*/
|
||||||
public class DefaultTokenServices implements AuthorizationServerTokenServices, ResourceServerTokenServices,
|
public class DefaultTokenServices implements AuthorizationServerTokenServices, ResourceServerTokenServices,
|
||||||
ConsumerTokenServices, InitializingBean {
|
ConsumerTokenServices, InitializingBean {
|
||||||
|
static final Logger _logger = LoggerFactory.getLogger(DefaultTokenServices.class);
|
||||||
|
|
||||||
private int refreshTokenValiditySeconds = 60 * 60 * 24 * 30; // default 30 days.
|
private int refreshTokenValiditySeconds = 60 * 60 * 24 * 30; // default 30 days.
|
||||||
|
|
||||||
@ -70,6 +79,10 @@ public class DefaultTokenServices implements AuthorizationServerTokenServices, R
|
|||||||
private TokenEnhancer accessTokenEnhancer;
|
private TokenEnhancer accessTokenEnhancer;
|
||||||
|
|
||||||
private AuthenticationManager authenticationManager;
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
private AppsService appsService;
|
||||||
|
|
||||||
|
private SessionManager sessionManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize these token services. If no random generator is set, one will be created.
|
* Initialize these token services. If no random generator is set, one will be created.
|
||||||
@ -125,6 +138,18 @@ public class DefaultTokenServices implements AuthorizationServerTokenServices, R
|
|||||||
if (refreshToken != null) {
|
if (refreshToken != null) {
|
||||||
tokenStore.storeRefreshToken(refreshToken, authentication);
|
tokenStore.storeRefreshToken(refreshToken, authentication);
|
||||||
}
|
}
|
||||||
|
//存储oauth、oidc等的token,用户退出时清除
|
||||||
|
if(authentication.getUserAuthentication().getPrincipal() instanceof SignPrincipal principal) {
|
||||||
|
_logger.debug("{}({}) , session {} access for logout clear ",
|
||||||
|
principal.getUsername(),principal.getUserId(),principal.getSessionId());
|
||||||
|
String clientId = authentication.getOAuth2Request().getRequestParameters().get(OAuth2Constants.PARAMETER.CLIENT_ID);
|
||||||
|
_logger.debug("client_id {} token {}",clientId,accessToken);
|
||||||
|
Apps app = appsService.get(clientId, true);
|
||||||
|
VisitedDto visited = new VisitedDto(app,principal.getSessionId());
|
||||||
|
visited.setToken(accessToken.getValue());
|
||||||
|
visited.setRefreshToken(accessToken.getRefreshToken().getValue());
|
||||||
|
sessionManager.visited(principal.getSessionId(), visited);
|
||||||
|
}
|
||||||
return accessToken;
|
return accessToken;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -432,4 +457,13 @@ public class DefaultTokenServices implements AuthorizationServerTokenServices, R
|
|||||||
this.clientDetailsService = clientDetailsService;
|
this.clientDetailsService = clientDetailsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAppsService(AppsService appsService) {
|
||||||
|
this.appsService = appsService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSessionManager(SessionManager sessionManager) {
|
||||||
|
this.sessionManager = sessionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -23,6 +23,7 @@ import java.security.spec.InvalidKeySpecException;
|
|||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.dromara.maxkey.authn.session.SessionManager;
|
||||||
import org.dromara.maxkey.authz.oauth2.common.OAuth2Constants;
|
import org.dromara.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||||
import org.dromara.maxkey.authz.oauth2.provider.ClientDetailsService;
|
import org.dromara.maxkey.authz.oauth2.provider.ClientDetailsService;
|
||||||
import org.dromara.maxkey.authz.oauth2.provider.OAuth2UserDetailsService;
|
import org.dromara.maxkey.authz.oauth2.provider.OAuth2UserDetailsService;
|
||||||
@ -48,6 +49,7 @@ import org.dromara.maxkey.crypto.jwt.encryption.service.impl.DefaultJwtEncryptio
|
|||||||
import org.dromara.maxkey.crypto.jwt.signer.service.impl.DefaultJwtSigningAndValidationService;
|
import org.dromara.maxkey.crypto.jwt.signer.service.impl.DefaultJwtSigningAndValidationService;
|
||||||
import org.dromara.maxkey.persistence.redis.RedisConnectionFactory;
|
import org.dromara.maxkey.persistence.redis.RedisConnectionFactory;
|
||||||
import org.dromara.maxkey.persistence.repository.LoginRepository;
|
import org.dromara.maxkey.persistence.repository.LoginRepository;
|
||||||
|
import org.dromara.maxkey.persistence.service.AppsService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
@ -259,12 +261,16 @@ public class Oauth20AutoConfiguration implements InitializingBean {
|
|||||||
DefaultTokenServices defaultTokenServices(
|
DefaultTokenServices defaultTokenServices(
|
||||||
JdbcClientDetailsService oauth20JdbcClientDetailsService,
|
JdbcClientDetailsService oauth20JdbcClientDetailsService,
|
||||||
TokenStore oauth20TokenStore,
|
TokenStore oauth20TokenStore,
|
||||||
OIDCIdTokenEnhancer tokenEnhancer) {
|
OIDCIdTokenEnhancer tokenEnhancer,
|
||||||
|
AppsService appsService,
|
||||||
|
SessionManager sessionManager) {
|
||||||
DefaultTokenServices tokenServices = new DefaultTokenServices();
|
DefaultTokenServices tokenServices = new DefaultTokenServices();
|
||||||
tokenServices.setClientDetailsService(oauth20JdbcClientDetailsService);
|
tokenServices.setClientDetailsService(oauth20JdbcClientDetailsService);
|
||||||
tokenServices.setTokenEnhancer(tokenEnhancer);
|
tokenServices.setTokenEnhancer(tokenEnhancer);
|
||||||
tokenServices.setTokenStore(oauth20TokenStore);
|
tokenServices.setTokenStore(oauth20TokenStore);
|
||||||
tokenServices.setSupportRefreshToken(true);
|
tokenServices.setSupportRefreshToken(true);
|
||||||
|
tokenServices.setAppsService(appsService);
|
||||||
|
tokenServices.setSessionManager(sessionManager);
|
||||||
_logger.debug("OAuth 2 Token Services init.");
|
_logger.debug("OAuth 2 Token Services init.");
|
||||||
return tokenServices;
|
return tokenServices;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,8 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.dromara.maxkey.authn.annotation.CurrentUser;
|
import org.dromara.maxkey.authn.annotation.CurrentUser;
|
||||||
import org.dromara.maxkey.authn.session.Session;
|
import org.dromara.maxkey.authn.session.Session;
|
||||||
import org.dromara.maxkey.authn.session.SessionManager;
|
import org.dromara.maxkey.authn.session.SessionManager;
|
||||||
|
import org.dromara.maxkey.authn.session.VisitedDto;
|
||||||
|
import org.dromara.maxkey.authz.oauth2.provider.token.DefaultTokenServices;
|
||||||
import org.dromara.maxkey.authz.singlelogout.DefaultSingleLogout;
|
import org.dromara.maxkey.authz.singlelogout.DefaultSingleLogout;
|
||||||
import org.dromara.maxkey.authz.singlelogout.LogoutType;
|
import org.dromara.maxkey.authz.singlelogout.LogoutType;
|
||||||
import org.dromara.maxkey.authz.singlelogout.SamlSingleLogout;
|
import org.dromara.maxkey.authz.singlelogout.SamlSingleLogout;
|
||||||
@ -32,7 +34,6 @@ import org.dromara.maxkey.authz.singlelogout.SingleLogout;
|
|||||||
import org.dromara.maxkey.configuration.ApplicationConfig;
|
import org.dromara.maxkey.configuration.ApplicationConfig;
|
||||||
import org.dromara.maxkey.constants.ConstsProtocols;
|
import org.dromara.maxkey.constants.ConstsProtocols;
|
||||||
import org.dromara.maxkey.entity.Message;
|
import org.dromara.maxkey.entity.Message;
|
||||||
import org.dromara.maxkey.entity.apps.Apps;
|
|
||||||
import org.dromara.maxkey.entity.idm.UserInfo;
|
import org.dromara.maxkey.entity.idm.UserInfo;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -59,6 +60,9 @@ public class LogoutEndpoint {
|
|||||||
@Autowired
|
@Autowired
|
||||||
SessionManager sessionManager;
|
SessionManager sessionManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DefaultTokenServices oauth20TokenServices;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* for front end
|
* for front end
|
||||||
* @param currentUser
|
* @param currentUser
|
||||||
@ -73,11 +77,12 @@ public class LogoutEndpoint {
|
|||||||
Session session = sessionManager.get(sessionId);
|
Session session = sessionManager.get(sessionId);
|
||||||
if(session != null) {
|
if(session != null) {
|
||||||
logger.debug("/logout frontend clean Session id {}",session.getId());
|
logger.debug("/logout frontend clean Session id {}",session.getId());
|
||||||
Set<Entry<String, Apps>> entrySet = session.getAuthorizedApps().entrySet();
|
Set<Entry<String, VisitedDto>> entrySet = session.getVisited().entrySet();
|
||||||
|
|
||||||
Iterator<Entry<String, Apps>> iterator = entrySet.iterator();
|
Iterator<Entry<String, VisitedDto>> iterator = entrySet.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
Entry<String, Apps> mapEntry = iterator.next();
|
Entry<String, VisitedDto> mapEntry = iterator.next();
|
||||||
|
VisitedDto visited = mapEntry.getValue();
|
||||||
logger.debug("App Id : {} , {} " , mapEntry.getKey() ,mapEntry.getValue());
|
logger.debug("App Id : {} , {} " , mapEntry.getKey() ,mapEntry.getValue());
|
||||||
if( mapEntry.getValue().getLogoutType() == LogoutType.BACK_CHANNEL){
|
if( mapEntry.getValue().getLogoutType() == LogoutType.BACK_CHANNEL){
|
||||||
SingleLogout singleLogout;
|
SingleLogout singleLogout;
|
||||||
@ -86,7 +91,14 @@ public class LogoutEndpoint {
|
|||||||
}else {
|
}else {
|
||||||
singleLogout = new DefaultSingleLogout();
|
singleLogout = new DefaultSingleLogout();
|
||||||
}
|
}
|
||||||
singleLogout.sendRequest(session.getAuthentication(), mapEntry.getValue());
|
singleLogout.sendRequest(session.getAuthentication(), visited);
|
||||||
|
}
|
||||||
|
//oauth , oidc revoke token
|
||||||
|
if(visited.getProtocol().equalsIgnoreCase(ConstsProtocols.OAUTH20)
|
||||||
|
||visited.getProtocol().equalsIgnoreCase(ConstsProtocols.OAUTH21)
|
||||||
|
||visited.getProtocol().equalsIgnoreCase(ConstsProtocols.OPEN_ID_CONNECT10)) {
|
||||||
|
oauth20TokenServices.revokeToken(visited.getToken());
|
||||||
|
logger.debug("revoke token");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//terminate session
|
//terminate session
|
||||||
|
|||||||
@ -101,8 +101,7 @@ public class SingleSignOnInterceptor implements AsyncHandlerInterceptor {
|
|||||||
logger.debug("appId {}",appId);
|
logger.debug("appId {}",appId);
|
||||||
app = appsService.get(appId,true);
|
app = appsService.get(appId,true);
|
||||||
}else if(requestURI.contains("/authz/oauth/v20/authorize")) {//oauth
|
}else if(requestURI.contains("/authz/oauth/v20/authorize")) {//oauth
|
||||||
app = appsService.get(
|
app = appsService.get(request.getParameter(OAuth2Constants.PARAMETER.CLIENT_ID),true);
|
||||||
request.getParameter(OAuth2Constants.PARAMETER.CLIENT_ID),true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user