LogoutEndpoint.java 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.maxkey.web.endpoint;
  17. import java.util.Iterator;
  18. import java.util.Set;
  19. import java.util.UUID;
  20. import java.util.Map.Entry;
  21. import javax.servlet.http.HttpServletRequest;
  22. import javax.servlet.http.HttpServletResponse;
  23. import org.maxkey.authn.SigninPrincipal;
  24. import org.maxkey.authn.online.OnlineTicket;
  25. import org.maxkey.authn.online.OnlineTicketServices;
  26. import org.maxkey.authn.realm.AbstractAuthenticationRealm;
  27. import org.maxkey.authz.singlelogout.SamlSingleLogout;
  28. import org.maxkey.authz.singlelogout.DefaultSingleLogout;
  29. import org.maxkey.authz.singlelogout.LogoutType;
  30. import org.maxkey.authz.singlelogout.SingleLogout;
  31. import org.maxkey.configuration.ApplicationConfig;
  32. import org.maxkey.constants.ConstantsProtocols;
  33. import org.maxkey.domain.apps.Apps;
  34. import org.maxkey.web.WebConstants;
  35. import org.maxkey.web.WebContext;
  36. import org.slf4j.Logger;
  37. import org.slf4j.LoggerFactory;
  38. import org.springframework.beans.factory.annotation.Autowired;
  39. import org.springframework.beans.factory.annotation.Qualifier;
  40. import org.springframework.security.core.context.SecurityContextHolder;
  41. import org.springframework.security.web.savedrequest.SavedRequest;
  42. import org.springframework.stereotype.Controller;
  43. import org.springframework.web.bind.annotation.RequestMapping;
  44. import org.springframework.web.bind.annotation.RequestParam;
  45. import org.springframework.web.servlet.ModelAndView;
  46. import io.swagger.annotations.Api;
  47. import io.swagger.annotations.ApiOperation;
  48. @Api(tags = "1-3-单点注销接口文档模块")
  49. @Controller
  50. public class LogoutEndpoint {
  51. private static Logger _logger = LoggerFactory.getLogger(LogoutEndpoint.class);
  52. public static final String RE_LOGIN_URL = "reLoginUrl";
  53. @Autowired
  54. @Qualifier("authenticationRealm")
  55. AbstractAuthenticationRealm authenticationRealm;
  56. @Autowired
  57. ApplicationConfig applicationConfig;
  58. @Autowired
  59. @Qualifier("onlineTicketServices")
  60. protected OnlineTicketServices onlineTicketServices;
  61. @ApiOperation(value = "单点注销接口", notes = "reLoginUrl跳转地址",httpMethod="GET")
  62. @RequestMapping(value={"/logout"})
  63. public ModelAndView logout(
  64. HttpServletRequest request,
  65. HttpServletResponse response,
  66. @RequestParam(value=RE_LOGIN_URL,required=false) String reLoginUrl){
  67. return logoutModelAndView(request,response,"loggedout",reLoginUrl);
  68. }
  69. @ApiOperation(value = "登录超时接口", notes = "",httpMethod="GET")
  70. @RequestMapping(value={"/timeout"})
  71. public ModelAndView timeout(HttpServletRequest request, HttpServletResponse response){
  72. return logoutModelAndView(request,response,"timeout",null);
  73. }
  74. private ModelAndView logoutModelAndView(
  75. HttpServletRequest request,
  76. HttpServletResponse response,
  77. String viewName,
  78. String reLoginUrl){
  79. ModelAndView modelAndView = new ModelAndView();
  80. authenticationRealm.logout(response);
  81. if(reLoginUrl==null){
  82. SavedRequest firstSavedRequest = (SavedRequest)WebContext.getAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER);
  83. reLoginUrl=WebContext.getHttpContextPath()+"/login";
  84. if(firstSavedRequest!=null){
  85. reLoginUrl= firstSavedRequest.getRedirectUrl();
  86. WebContext.removeAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER);
  87. }
  88. }
  89. //not start with http or https
  90. if(reLoginUrl!=null && !reLoginUrl.toLowerCase().startsWith("http")) {
  91. reLoginUrl=WebContext.getHttpContextPath()+"/"+reLoginUrl;
  92. }
  93. _logger.debug("re Login URL : "+ reLoginUrl);
  94. modelAndView.addObject("reloginUrl",reLoginUrl);
  95. String onlineTicketId = ((SigninPrincipal)WebContext.getAuthentication().getPrincipal()).getOnlineTicket().getTicketId();
  96. OnlineTicket onlineTicket = onlineTicketServices.get(onlineTicketId);
  97. Set<Entry<String, Apps>> entrySet = onlineTicket.getAuthorizedApps().entrySet();
  98. Iterator<Entry<String, Apps>> iterator = entrySet.iterator();
  99. while (iterator.hasNext()) {
  100. Entry<String, Apps> mapEntry = iterator.next();
  101. _logger.debug("App Id : "+ mapEntry.getKey()+ " , " +mapEntry.getValue());
  102. if( mapEntry.getValue().getLogoutType() == LogoutType.BACK_CHANNEL){
  103. SingleLogout singleLogout;
  104. if(mapEntry.getValue().getProtocol().equalsIgnoreCase(ConstantsProtocols.CAS)) {
  105. singleLogout =new SamlSingleLogout();
  106. }else {
  107. singleLogout = new DefaultSingleLogout();
  108. }
  109. singleLogout.sendRequest(onlineTicket.getAuthentication(), mapEntry.getValue());
  110. }
  111. }
  112. onlineTicketServices.remove(onlineTicketId);
  113. //remove ONLINE_TICKET cookie
  114. WebContext.expiryCookie(WebContext.getResponse(),
  115. this.applicationConfig.getBaseDomainName(),
  116. WebConstants.ONLINE_TICKET_NAME,
  117. UUID.randomUUID().toString());
  118. request.getSession().invalidate();
  119. SecurityContextHolder.clearContext();
  120. modelAndView.setViewName(viewName);
  121. return modelAndView;
  122. }
  123. }