Jelajahi Sumber

#IDGR9O cas登录grantingTicket生成的url会有重复参数

shimingxy 4 hari lalu
induk
melakukan
c9810dd062

+ 82 - 0
maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/http/HttpUtils.java

@@ -0,0 +1,82 @@
+/*
+ * Copyright [2025] [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.http;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.lang3.ObjectUtils;
+
+public class HttpUtils {
+
+    /**
+     * https://cas.maxkey.top/casserver/authz?aaa=aaa&bbb=bbb <br/>
+     * return <br/>
+     * https://cas.maxkey.top/casserver/authz
+     * @param param
+     * @return
+     */
+    public static String requestUrl(String param){
+        String url = param;
+        if(param.indexOf("?") > -1) {
+            url = param.substring(0, param.indexOf("?"));
+        }
+        return url;
+    }
+    
+    /**
+     * 把map参数加到url后
+     * @param url
+     * @param parameterMap
+     * @return 
+     */
+    public static String appendToUrl(String url,Map<String,String> parameterMap){
+        StringBuffer appendedUrl = new StringBuffer(url);
+        if(ObjectUtils.isNotEmpty(parameterMap)) {
+            for (Entry<String, String> entry : parameterMap.entrySet()) {
+                appendedUrl.append((appendedUrl.indexOf("?") == -1)?"?":"&")
+                           .append(entry.getKey()).append("=").append(entry.getValue());
+            }
+        }
+        return appendedUrl.toString();
+    }
+    
+    /**
+     * https://cas.maxkey.top/casserver/authz?aaa=aaa&bbb=bbb <br/>
+     * 把aaa=aaa&bbb=bbb转换成map
+     * @param param
+     * @return Map
+     */
+    public static Map<String,String> queryStringToMap(String param){
+        String urlParam = param;
+        Map<String,String> paramMap = new HashMap<String,String>();
+        if(param.indexOf("?") > -1) {
+            urlParam = param.substring(param.indexOf("?") + 1);
+        }
+        String[] params =  urlParam.split("&");
+        for(String keyValue : params){
+           String[] paramValue = keyValue.split("=");
+           if(paramValue.length == 2){
+               paramMap.put(paramValue[0], paramValue[1]);
+           }
+        }
+        return paramMap;
+     }
+}

+ 40 - 55
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/dromara/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java

@@ -14,22 +14,20 @@
  * limitations under the License.
  */
  
-
-/**
- * 
- */
 package org.dromara.maxkey.authz.cas.endpoint;
 
 import java.security.Principal;
+import java.util.HashMap;
 import java.util.Map;
-import java.util.Map.Entry;
 
+import org.apache.commons.lang3.ObjectUtils;
 import org.dromara.maxkey.authn.session.VisitedDto;
 import org.dromara.maxkey.authn.web.AuthorizationUtils;
 import org.dromara.maxkey.authz.cas.ticket.CasConstants;
 import org.dromara.maxkey.authz.cas.ticket.ServiceTicketImpl;
 import org.dromara.maxkey.authz.singlelogout.LogoutType;
 import org.dromara.maxkey.entity.apps.AppsCasDetails;
+import org.dromara.maxkey.http.HttpUtils;
 import org.dromara.maxkey.web.WebConstants;
 import org.dromara.maxkey.web.WebContext;
 import org.slf4j.Logger;
@@ -61,9 +59,9 @@ public class CasAuthorizeEndpoint  extends CasBaseAuthorizeEndpoint{
                                  HttpServletRequest request,
                                  HttpServletResponse response
             ){
-        
-        AppsCasDetails  casDetails = casDetailsService.getAppDetails(casService , true);
-        
+    	String queryService  = HttpUtils.requestUrl(casService);
+    	_logger.debug("service {}" , queryService);
+        AppsCasDetails  casDetails = casDetailsService.getAppDetails(queryService , true);
         return buildCasModelAndView(request,response,casDetails,casService);
     }
     
@@ -90,20 +88,21 @@ public class CasAuthorizeEndpoint  extends CasBaseAuthorizeEndpoint{
             return modelAndView;
         }
         
-        _logger.debug("Detail {}" , casDetails);
-        Map<String, String> parameterMap = WebContext.getRequestParameterMap(request);
-        String service = casService;
-        _logger.debug("CAS Parameter service = {}" , service);
-        if(casService.indexOf("?") >-1 ) {
-            service = casService.substring(casService.indexOf("?") + 1);
-            if(service.indexOf("=") > -1) {
-                String [] parameterValues = service.split("=");
-                if(parameterValues.length == 2) {
-                    parameterMap.put(parameterValues[0], parameterValues[1]);
-                }
-            }
-            _logger.debug("CAS service with Parameter : {}" , parameterMap);
+        _logger.debug("CAS service = {} , Detail {}" , casService,casDetails);
+        Map<String, String> parameterMap = new HashMap<>();
+        //配置参数
+        Map<String,String> serviceParamMap = HttpUtils.queryStringToMap(casDetails.getCallbackUrl());
+        if(ObjectUtils.isNotEmpty(serviceParamMap)) {
+            parameterMap.putAll(serviceParamMap);
         }
+        _logger.debug("CAS CallbackUrl Parameter : {}" , parameterMap);
+        //请求参数
+        Map<String, String> requestParameterMap = WebContext.getRequestParameterMap(request);
+        if(ObjectUtils.isNotEmpty(requestParameterMap)) {
+            parameterMap.putAll(requestParameterMap);
+        }
+        parameterMap.put(CasConstants.PARAMETER.SERVICE, casService);
+        _logger.debug("CAS service with Parameter : {}" , parameterMap);
         WebContext.setAttribute(CasConstants.PARAMETER.PARAMETER_MAP, parameterMap);
         WebContext.setAttribute(CasConstants.PARAMETER.ENDPOINT_CAS_DETAILS, casDetails);
         WebContext.setAttribute(WebConstants.SINGLE_SIGN_ON_APP_ID, casDetails.getId());
@@ -118,49 +117,35 @@ public class CasAuthorizeEndpoint  extends CasBaseAuthorizeEndpoint{
                                         HttpServletResponse response){
         ModelAndView modelAndView = new ModelAndView("authorize/cas_sso_submint");
         AppsCasDetails casDetails = (AppsCasDetails)WebContext.getAttribute(CasConstants.PARAMETER.ENDPOINT_CAS_DETAILS);
-        
         ServiceTicketImpl serviceTicket = new ServiceTicketImpl(AuthorizationUtils.getAuthentication(),casDetails);
-        
-        _logger.trace("CAS start create ticket ... ");
-        String ticket = ticketServices.createTicket(serviceTicket,casDetails.getExpires());
-        _logger.trace("CAS ticket {} created . " , ticket);
-        
-        StringBuffer callbackUrl = new StringBuffer(casDetails.getCallbackUrl());
-        if(casDetails.getCallbackUrl().indexOf("?")==-1) {
-            callbackUrl.append("?");
-        }
-        
-        if(callbackUrl.indexOf("&") != -1 ||callbackUrl.indexOf("=") != -1) {
-            callbackUrl.append("&");
-        }
-        
-        //append ticket
-        callbackUrl.append(CasConstants.PARAMETER.TICKET).append("=").append(ticket);
-        
-        callbackUrl.append("&");
-        //append service
-        callbackUrl.append(CasConstants.PARAMETER.SERVICE).append("=").append(casDetails.getService());
-        
-        //增加可自定义的参数
-        if(WebContext.getAttribute(CasConstants.PARAMETER.PARAMETER_MAP)!=null) {
-            @SuppressWarnings("unchecked")
-            Map <String, String> parameterMap = (Map <String, String>)WebContext.getAttribute(CasConstants.PARAMETER.PARAMETER_MAP);
-            parameterMap.remove(CasConstants.PARAMETER.TICKET);
-            parameterMap.remove(CasConstants.PARAMETER.SERVICE);
-            for (Entry<String, String> entry : parameterMap.entrySet()) {
-                callbackUrl.append("&").append(entry.getKey()).append("=").append(entry.getValue());
-            }
+        @SuppressWarnings("unchecked")
+        Map <String, String> parameterMap = (Map <String, String>)WebContext.getAttribute(CasConstants.PARAMETER.PARAMETER_MAP);
+        if(parameterMap == null) {
+            parameterMap = new HashMap<>();
         }
         
+        String ticket = ticketServices.createTicket(serviceTicket,casDetails.getExpires());
+        _logger.trace("CAS ticket {} created for App {}  Name {} " , ticket , casDetails.getId(),casDetails.getAppName());
+
         if(casDetails.getLogoutType()==LogoutType.BACK_CHANNEL) {
-            _logger.debug("CAS LogoutType BACK_CHANNEL ... ");
             String sessionId = AuthorizationUtils.getPrincipal().getSessionId();
             VisitedDto visited = new VisitedDto(casDetails,ticket);
             sessionManager.visited(sessionId, visited);
-            _logger.debug("App id {} , name {} , CAS LogoutType BACK_CHANNEL ... " , casDetails.getId(),casDetails.getAppName());
+            _logger.debug("App CAS LogoutType BACK_CHANNEL ... ");
         }
         
-        _logger.debug("redirect to CAS Client URL {}" , callbackUrl);
+        //去除?和后面的参数
+        String callbackUri = HttpUtils.requestUrl(casDetails.getCallbackUrl());
+        //ticket
+        parameterMap.put(CasConstants.PARAMETER.TICKET, ticket);
+        //service
+        if(!parameterMap.containsKey(CasConstants.PARAMETER.SERVICE)) {
+            parameterMap.put(CasConstants.PARAMETER.SERVICE, casDetails.getService());
+        }
+        //增加可自定义的参数
+        String callbackUrl = HttpUtils.appendToUrl(callbackUri, parameterMap);
+        
+        _logger.debug("redirect to CAS URL {}" , callbackUrl);
         modelAndView.addObject("callbackUrl", callbackUrl.toString());
         return modelAndView;
     }