mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-06 17:08:29 +08:00
SingleLogout
This commit is contained in:
parent
a90fb9ad20
commit
49246f0ffa
@ -1,16 +0,0 @@
|
|||||||
package org.maxkey.authz.singlelogout;
|
|
||||||
|
|
||||||
public class CasSingleLogout extends SingleLogout{
|
|
||||||
|
|
||||||
public String logoutRequestMessage=
|
|
||||||
"<samlp:LogoutRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"%s\" Version=\"2.0\" "
|
|
||||||
+ "IssueInstant=\"%s\"><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">%s"
|
|
||||||
+ "</saml:NameID><samlp:SessionIndex>%s</samlp:SessionIndex></samlp:LogoutRequest>";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRequest() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,15 +1,24 @@
|
|||||||
package org.maxkey.authz.singlelogout;
|
package org.maxkey.authz.singlelogout;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.maxkey.authn.SigninPrincipal;
|
||||||
|
import org.maxkey.domain.apps.Apps;
|
||||||
|
import org.maxkey.util.DateUtils;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
public class DefaultSingleLogout extends SingleLogout{
|
public class DefaultSingleLogout extends SingleLogout{
|
||||||
|
|
||||||
public String logoutRequestMessage=
|
|
||||||
"<samlp:LogoutRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"%s\" Version=\"2.0\" "
|
|
||||||
+ "IssueInstant=\"%s\"><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">%s"
|
|
||||||
+ "</saml:NameID><samlp:SessionIndex>%s</samlp:SessionIndex></samlp:LogoutRequest>";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendRequest() {
|
public void sendRequest(Authentication authentication,Apps logoutApp) {
|
||||||
// TODO Auto-generated method stub
|
HashMap<String,Object> logoutParameters = new HashMap<String,Object>();
|
||||||
|
logoutParameters.put("id", UUID.randomUUID().toString());
|
||||||
|
logoutParameters.put("principal", authentication.getName());
|
||||||
|
logoutParameters.put("request", "logoutRequest");
|
||||||
|
logoutParameters.put("issueInstant", DateUtils.getCurrentDateAsString(DateUtils.FORMAT_DATE_ISO_TIMESTAMP));
|
||||||
|
logoutParameters.put("ticket", ((SigninPrincipal)authentication.getPrincipal()).getOnlineTicket().getTicketId());
|
||||||
|
postMessage(logoutApp.getLogoutUrl(),logoutParameters);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,40 @@
|
|||||||
|
package org.maxkey.authz.singlelogout;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.maxkey.domain.apps.Apps;
|
||||||
|
import org.maxkey.util.DateUtils;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
|
public class SamlSingleLogout extends SingleLogout{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter name that contains the logout request.
|
||||||
|
*/
|
||||||
|
public static final String LOGOUT_REQUEST_PARAMETER = "logoutRequest";
|
||||||
|
|
||||||
|
public static final String logoutRequestMessage=
|
||||||
|
"<samlp:LogoutRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"%s\" Version=\"2.0\" "
|
||||||
|
+ "IssueInstant=\"%s\"><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">%s"
|
||||||
|
+ "</saml:NameID><samlp:SessionIndex>%s</samlp:SessionIndex></samlp:LogoutRequest>";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRequest(Authentication authentication,Apps logoutApp) {
|
||||||
|
String requestMessage = String.format(logoutRequestMessage,
|
||||||
|
UUID.randomUUID().toString(),
|
||||||
|
DateUtils.getCurrentDateAsString(DateUtils.FORMAT_DATE_ISO_TIMESTAMP),
|
||||||
|
authentication.getName(),
|
||||||
|
logoutApp.getOnlineTicket()
|
||||||
|
);
|
||||||
|
|
||||||
|
HashMap<String,Object> logoutParameters = new HashMap<String,Object>();
|
||||||
|
logoutParameters.put(LOGOUT_REQUEST_PARAMETER, requestMessage);
|
||||||
|
postMessage(logoutApp.getLogoutUrl(),logoutParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SamlSingleLogout() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,7 +1,101 @@
|
|||||||
package org.maxkey.authz.singlelogout;
|
package org.maxkey.authz.singlelogout;
|
||||||
|
|
||||||
public abstract class SingleLogout {
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.NameValuePair;
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.maxkey.domain.apps.Apps;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
|
public abstract class SingleLogout {
|
||||||
|
private static final Logger _logger = LoggerFactory.getLogger(SingleLogout.class);
|
||||||
|
|
||||||
public abstract void sendRequest() ;
|
public abstract void sendRequest(Authentication authentication,Apps logoutApp) ;
|
||||||
|
|
||||||
|
public void postMessage(String url,Map<String, Object> paramMap) {
|
||||||
|
// 创建httpClient实例
|
||||||
|
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||||
|
CloseableHttpResponse httpResponse = null;
|
||||||
|
// 创建httpPost远程连接实例
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
// 配置请求参数实例
|
||||||
|
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
|
||||||
|
.setConnectionRequestTimeout(35000)// 设置连接请求超时时间
|
||||||
|
.setSocketTimeout(60000)// 设置读取数据连接超时时间
|
||||||
|
.build();
|
||||||
|
// 为httpPost实例设置配置
|
||||||
|
httpPost.setConfig(requestConfig);
|
||||||
|
// 设置请求头
|
||||||
|
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
// 封装post请求参数
|
||||||
|
if (null != paramMap && paramMap.size() > 0) {
|
||||||
|
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
|
||||||
|
// 通过map集成entrySet方法获取entity
|
||||||
|
Set<Entry<String, Object>> entrySet = paramMap.entrySet();
|
||||||
|
// 循环遍历,获取迭代器
|
||||||
|
Iterator<Entry<String, Object>> iterator = entrySet.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Entry<String, Object> mapEntry = iterator.next();
|
||||||
|
_logger.debug("Name " + mapEntry.getKey() + " , Value " +mapEntry.getValue());
|
||||||
|
nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为httpPost设置封装好的请求参数
|
||||||
|
try {
|
||||||
|
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
_logger.debug("Post URL " + url + " , Post Message \n" +
|
||||||
|
httpPost.getEntity().toString()
|
||||||
|
);
|
||||||
|
// httpClient对象执行post请求,并返回响应参数对象
|
||||||
|
httpResponse = httpClient.execute(httpPost);
|
||||||
|
// 从响应对象中获取响应内容
|
||||||
|
HttpEntity entity = httpResponse.getEntity();
|
||||||
|
_logger.debug("Http Response StatusCode " +
|
||||||
|
httpResponse.getStatusLine().getStatusCode()+
|
||||||
|
" , Content " +EntityUtils.toString(entity)
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
// 关闭资源
|
||||||
|
if (null != httpResponse) {
|
||||||
|
try {
|
||||||
|
httpResponse.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (null != httpClient) {
|
||||||
|
try {
|
||||||
|
httpClient.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,13 +17,23 @@
|
|||||||
|
|
||||||
package org.maxkey.web.endpoint;
|
package org.maxkey.web.endpoint;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.maxkey.authn.SigninPrincipal;
|
import org.maxkey.authn.SigninPrincipal;
|
||||||
|
import org.maxkey.authn.online.OnlineTicket;
|
||||||
import org.maxkey.authn.online.OnlineTicketServices;
|
import org.maxkey.authn.online.OnlineTicketServices;
|
||||||
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
|
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
|
||||||
|
import org.maxkey.authz.singlelogout.SamlSingleLogout;
|
||||||
|
import org.maxkey.authz.singlelogout.DefaultSingleLogout;
|
||||||
|
import org.maxkey.authz.singlelogout.LogoutType;
|
||||||
|
import org.maxkey.authz.singlelogout.SingleLogout;
|
||||||
import org.maxkey.configuration.ApplicationConfig;
|
import org.maxkey.configuration.ApplicationConfig;
|
||||||
|
import org.maxkey.constants.ConstantsProtocols;
|
||||||
|
import org.maxkey.domain.apps.Apps;
|
||||||
import org.maxkey.web.WebConstants;
|
import org.maxkey.web.WebConstants;
|
||||||
import org.maxkey.web.WebContext;
|
import org.maxkey.web.WebContext;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -95,7 +105,26 @@ public class LogoutEndpoint {
|
|||||||
_logger.debug("re Login URL : "+ reLoginUrl);
|
_logger.debug("re Login URL : "+ reLoginUrl);
|
||||||
|
|
||||||
modelAndView.addObject("reloginUrl",reLoginUrl);
|
modelAndView.addObject("reloginUrl",reLoginUrl);
|
||||||
onlineTicketServices.remove(((SigninPrincipal)WebContext.getAuthentication().getPrincipal()).getOnlineTicket().getTicketId());
|
String onlineTicketId = ((SigninPrincipal)WebContext.getAuthentication().getPrincipal()).getOnlineTicket().getTicketId();
|
||||||
|
OnlineTicket onlineTicket = onlineTicketServices.get(onlineTicketId);
|
||||||
|
|
||||||
|
Set<Entry<String, Apps>> entrySet = onlineTicket.getAuthorizedApps().entrySet();
|
||||||
|
|
||||||
|
Iterator<Entry<String, Apps>> iterator = entrySet.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Entry<String, Apps> mapEntry = iterator.next();
|
||||||
|
_logger.debug("App Id : "+ mapEntry.getKey()+ " , " +mapEntry.getValue());
|
||||||
|
if( mapEntry.getValue().getLogoutType() == LogoutType.BACK_CHANNEL){
|
||||||
|
SingleLogout singleLogout;
|
||||||
|
if(mapEntry.getValue().getProtocol().equalsIgnoreCase(ConstantsProtocols.CAS)) {
|
||||||
|
singleLogout =new SamlSingleLogout();
|
||||||
|
}else {
|
||||||
|
singleLogout = new DefaultSingleLogout();
|
||||||
|
}
|
||||||
|
singleLogout.sendRequest(onlineTicket.getAuthentication(), mapEntry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onlineTicketServices.remove(onlineTicketId);
|
||||||
request.getSession().invalidate();
|
request.getSession().invalidate();
|
||||||
SecurityContextHolder.clearContext();
|
SecurityContextHolder.clearContext();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user