cas的url中去掉jsessionid

 Servlet3.0规范中的<tracking-mode>允许你定义JSESSIONID是存储在cookie中还是URL参数中。如果会话ID存储在URL中,那么它可能会被无意的存储

 在多个地方,包括浏览器历史、代理服务器日志、引用日志和web日志等。暴露了会话ID使得网站被session劫持攻击的几率大增。 

在用CAS做系统单点登录时,在成功的跳转后,链接会带上;jsessionid=xxx的情况,下面就是如何去掉jssessionid的方法: 

1.在项目的web.xml中加上下面的配置

<session-config>
     <session-timeout>30</session-timeout>
     <tracking-mode>COOKIE</tracking-mode> 
</session-config>

2.如果上面的方法没有解决问题,可以尝试下面的方法(html带上;jsessionid=xxx会报错,所以,要在跳转前讲;jsessionid=xxx去掉,

默认第一次访问的时候,如果session没值,就会带上;jsessionid=xxx):

public static final String cleanupUrl(final String url) {                                                                                                                                                         
        if (url == null) {
            return null;
        }
 
        final int jsessionPosition = url.indexOf(";jsession");
 
        if (jsessionPosition == -1) {
            return url;
        }
 
        final int questionMarkPosition = url.indexOf("?");
 
        if (questionMarkPosition < jsessionPosition) {
            return url.substring(0, url.indexOf(";jsession"));
        }
 
        return url.substring(0, jsessionPosition)
            + url.substring(questionMarkPosition);
    }

default:
//return new ExternalRedirect(serviceResponse.getUrl());//注释源码                                                                                                                                
return new ExternalRedirect(UrlUtils.cleanupUrl(serviceResponse.getUrl()));//清除url中jsessionid 

(注意版本的不同,但是只要找到处理链接的的文件就可以,在3.5.2的版本中,只需要修改CommonUtils的文件即可)

/**
 * Licensed to Jasig under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Jasig licenses this file to you 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.jasig.cas.client.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.validation.ProxyList;
import org.jasig.cas.client.validation.ProxyListEditor;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.net.URL;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.TimeZone;

/**
 * Common utilities so that we don't need to include Commons Lang.
 *
 * @author Scott Battaglia
 * @version $Revision: 11729 $ $Date: 2007-09-26 14:22:30 -0400 (Tue, 26 Sep
 *          2007) $
 * @since 3.0
 */
public final class CommonUtils {

	/** Instance of Commons Logging. */
	private static final Log LOG = LogFactory.getLog(CommonUtils.class);

	/**
	 * Constant representing the ProxyGrantingTicket IOU Request Parameter.
	 */
	private static final String PARAM_PROXY_GRANTING_TICKET_IOU = "pgtIou";

	/**
	 * Constant representing the ProxyGrantingTicket Request Parameter.
	 */
	private static final String PARAM_PROXY_GRANTING_TICKET = "pgtId";

	private CommonUtils() {
		// nothing to do
	}

	public static String formatForUtcTime(final Date date) {
		final DateFormat dateFormat = new SimpleDateFormat(
				"yyyy-MM-dd'T'HH:mm:ss'Z'");
		dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
		return dateFormat.format(date);
	}

	/**
	 * Check whether the object is null or not. If it is, throw an exception and
	 * display the message.
	 *
	 * @param object
	 *            the object to check.
	 * @param message
	 *            the message to display if the object is null.
	 */
	public static void assertNotNull(final Object object, final String message) {
		if (object == null) {
			throw new IllegalArgumentException(message);
		}
	}

	/**
	 * Check whether the collection is null or empty. If it is, throw an
	 * exception and display the message.
	 *
	 * @param c
	 *            the collecion to check.
	 * @param message
	 *            the message to display if the object is null.
	 */
	public static void assertNotEmpty(final Collection<?> c,
			final String message) {
		assertNotNull(c, message);
		if (c.isEmpty()) {
			throw new IllegalArgumentException(message);
		}
	}

	/**
	 * Assert that the statement is true, otherwise throw an exception with the
	 * provided message.
	 *
	 * @param cond
	 *            the codition to assert is true.
	 * @param message
	 *            the message to display if the condition is not true.
	 */
	public static void assertTrue(final boolean cond, final String message) {
		if (!cond) {
			throw new IllegalArgumentException(message);
		}
	}

	/**
	 * Determines whether the String is null or of length 0.
	 *
	 * @param string
	 *            the string to check
	 * @return true if its null or length of 0, false otherwise.
	 */
	public static boolean isEmpty(final String string) {
		return string == null || string.length() == 0;
	}

	/**
	 * Determines if the String is not empty. A string is not empty if it is not
	 * null and has a length > 0.
	 *
	 * @param string
	 *            the string to check
	 * @return true if it is not empty, false otherwise.
	 */
	public static boolean isNotEmpty(final String string) {
		return !isEmpty(string);
	}

	/**
	 * Determines if a String is blank or not. A String is blank if its empty or
	 * if it only contains spaces.
	 *
	 * @param string
	 *            the string to check
	 * @return true if its blank, false otherwise.
	 */
	public static boolean isBlank(final String string) {
		return isEmpty(string) || string.trim().length() == 0;
	}

	/**
	 * Determines if a string is not blank. A string is not blank if it contains
	 * at least one non-whitespace character.
	 *
	 * @param string
	 *            the string to check.
	 * @return true if its not blank, false otherwise.
	 */
	public static boolean isNotBlank(final String string) {
		return !isBlank(string);
	}

	/**
	 * Constructs the URL to use to redirect to the CAS server.
	 *
	 * @param casServerLoginUrl
	 *            the CAS Server login url.
	 * @param serviceParameterName
	 *            the name of the parameter that defines the service.
	 * @param serviceUrl
	 *            the actual service's url.
	 * @param renew
	 *            whether we should send renew or not.
	 * @param gateway
	 *            where we should send gateway or not.
	 * @return the fully constructed redirect url.
	 */
	public static String constructRedirectUrl(final String casServerLoginUrl,
			final String serviceParameterName, final String serviceUrl,
			final boolean renew, final boolean gateway) {
		try {
			return casServerLoginUrl
					+ (casServerLoginUrl.indexOf("?") != -1 ? "&" : "?")
					+ serviceParameterName + "="
					+ URLEncoder.encode(serviceUrl, "UTF-8")
					+ (renew ? "&renew=true" : "")
					+ (gateway ? "&gateway=true" : "");
		} catch (final UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	public static void readAndRespondToProxyReceptorRequest(
			final HttpServletRequest request,
			final HttpServletResponse response,
			final ProxyGrantingTicketStorage proxyGrantingTicketStorage)
			throws IOException {
		final String proxyGrantingTicketIou = request
				.getParameter(PARAM_PROXY_GRANTING_TICKET_IOU);

		final String proxyGrantingTicket = request
				.getParameter(PARAM_PROXY_GRANTING_TICKET);

		if (CommonUtils.isBlank(proxyGrantingTicket)
				|| CommonUtils.isBlank(proxyGrantingTicketIou)) {
			response.getWriter().write("");
			return;
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("Received proxyGrantingTicketId [" + proxyGrantingTicket
					+ "] for proxyGrantingTicketIou [" + proxyGrantingTicketIou
					+ "]");
		}

		proxyGrantingTicketStorage.save(proxyGrantingTicketIou,
				proxyGrantingTicket);

		if (LOG.isDebugEnabled()) {
			LOG.debug("Successfully saved proxyGrantingTicketId ["
					+ proxyGrantingTicket + "] for proxyGrantingTicketIou ["
					+ proxyGrantingTicketIou + "]");
		}

		response.getWriter().write("<?xml version="1.0"?>");
		response.getWriter()
				.write("<casClient:proxySuccess xmlns:casClient="http://www.yale.edu/tp/casClient" />");
	}

	/**
	 * Constructs a service url from the HttpServletRequest or from the given
	 * serviceUrl. Prefers the serviceUrl provided if both a serviceUrl and a
	 * serviceName.
	 *
	 * @param request
	 *            the HttpServletRequest
	 * @param response
	 *            the HttpServletResponse
	 * @param service
	 *            the configured service url (this will be used if not null)
	 * @param serverName
	 *            the server name to use to constuct the service url if the
	 *            service param is empty
	 * @param artifactParameterName
	 *            the artifact parameter name to remove (i.e. ticket)
	 * @param encode
	 *            whether to encode the url or not (i.e. Jsession).
	 * @return the service url to use.
	 */
	public static String constructServiceUrl(final HttpServletRequest request,
			final HttpServletResponse response, final String service,
			final String serverName, final String artifactParameterName,
			final boolean encode) {
		if (CommonUtils.isNotBlank(service)) {
			return encode ? response.encodeURL(service) : service;
		}

		final StringBuilder buffer = new StringBuilder();

		if (!serverName.startsWith("https://")
				&& !serverName.startsWith("http://")) {
			buffer.append(request.isSecure() ? "https://" : "http://");
		}

		buffer.append(serverName);
		buffer.append(request.getRequestURI());

		if (CommonUtils.isNotBlank(request.getQueryString())) {
			final int location = request.getQueryString().indexOf(
					artifactParameterName + "=");

			if (location == 0) {
				final String returnValue = encode ? response.encodeURL(buffer
						.toString()) : buffer.toString();
				if (LOG.isDebugEnabled()) {
					LOG.debug("serviceUrl generated: " + returnValue);
				}
				return cleanupUrl(returnValue);
			}

			buffer.append("?");

			if (location == -1) {
				buffer.append(request.getQueryString());
			} else if (location > 0) {
				final int actualLocation = request.getQueryString().indexOf(
						"&" + artifactParameterName + "=");

				if (actualLocation == -1) {
					buffer.append(request.getQueryString());
				} else if (actualLocation > 0) {
					buffer.append(request.getQueryString().substring(0,
							actualLocation));
				}
			}
		}

		final String returnValue = encode ? response.encodeURL(buffer
				.toString()) : buffer.toString();
		if (LOG.isDebugEnabled()) {
			LOG.debug("serviceUrl generated: " + returnValue);
		}
		return cleanupUrl(returnValue);
	}

	/**
	 * Safe method for retrieving a parameter from the request without
	 * disrupting the reader UNLESS the parameter actually exists in the query
	 * string.
	 * <p>
	 * Note, this does not work for POST Requests for "logoutRequest". It works
	 * for all other CAS POST requests because the parameter is ALWAYS in the
	 * GET request.
	 * <p>
	 * If we see the "logoutRequest" parameter we MUST treat it as if calling
	 * the standard request.getParameter.
	 *
	 * @param request
	 *            the request to check.
	 * @param parameter
	 *            the parameter to look for.
	 * @return the value of the parameter.
	 */
	public static String safeGetParameter(final HttpServletRequest request,
			final String parameter) {
		if ("POST".equals(request.getMethod())
				&& "logoutRequest".equals(parameter)) {
			LOG.debug("safeGetParameter called on a POST HttpServletRequest for LogoutRequest.  Cannot complete check safely.  Reverting to standard behavior for this Parameter");
			return request.getParameter(parameter);
		}
		return request.getQueryString() == null
				|| request.getQueryString().indexOf(parameter) == -1 ? null
				: request.getParameter(parameter);
	}

	/**
	 * Contacts the remote URL and returns the response.
	 *
	 * @param constructedUrl
	 *            the url to contact.
	 * @param encoding
	 *            the encoding to use.
	 * @return the response.
	 */
	public static String getResponseFromServer(final URL constructedUrl,
			final String encoding) {
		return getResponseFromServer(constructedUrl,
				HttpsURLConnection.getDefaultHostnameVerifier(), encoding);
	}

	/**
	 * Contacts the remote URL and returns the response.
	 *
	 * @param constructedUrl
	 *            the url to contact.
	 * @param hostnameVerifier
	 *            Host name verifier to use for HTTPS connections.
	 * @param encoding
	 *            the encoding to use.
	 * @return the response.
	 */
	public static String getResponseFromServer(final URL constructedUrl,
			final HostnameVerifier hostnameVerifier, final String encoding) {
		URLConnection conn = null;
		try {
			conn = constructedUrl.openConnection();
			if (conn instanceof HttpsURLConnection) {
				((HttpsURLConnection) conn)
						.setHostnameVerifier(hostnameVerifier);
			}
			final BufferedReader in;

			if (CommonUtils.isEmpty(encoding)) {
				in = new BufferedReader(new InputStreamReader(
						conn.getInputStream()));
			} else {
				in = new BufferedReader(new InputStreamReader(
						conn.getInputStream(), encoding));
			}

			String line;
			final StringBuilder stringBuffer = new StringBuilder(255);

			while ((line = in.readLine()) != null) {
				stringBuffer.append(line);
				stringBuffer.append("
");
			}
			return stringBuffer.toString();
		} catch (final Exception e) {
			LOG.error(e.getMessage(), e);
			throw new RuntimeException(e);
		} finally {
			if (conn != null && conn instanceof HttpURLConnection) {
				((HttpURLConnection) conn).disconnect();
			}
		}

	}

	/**
	 * Contacts the remote URL and returns the response.
	 *
	 * @param url
	 *            the url to contact.
	 * @param encoding
	 *            the encoding to use.
	 * @return the response.
	 */
	public static String getResponseFromServer(final String url, String encoding) {
		try {
			return getResponseFromServer(new URL(url), encoding);
		} catch (final MalformedURLException e) {
			throw new IllegalArgumentException(e);
		}
	}

	public static ProxyList createProxyList(final String proxies) {
		if (CommonUtils.isBlank(proxies)) {
			return new ProxyList();
		}

		final ProxyListEditor editor = new ProxyListEditor();
		editor.setAsText(proxies);
		return (ProxyList) editor.getValue();
	}

	/**
	 * Sends the redirect message and captures the exceptions that we can't
	 * possibly do anything with.
	 *
	 * @param response
	 *            the HttpServletResponse. CANNOT be NULL.
	 * @param url
	 *            the url to redirect to.
	 */
	public static void sendRedirect(final HttpServletResponse response,
			final String url) {
		try {
			response.sendRedirect(url);
		} catch (final Exception e) {
			LOG.warn(e.getMessage(), e);
		}

	}

	/**
	 *  cleanup jsessionid
	 *  
	 * @param url
	 * @return
	 */
	public static final String cleanupUrl(final String url) {
		
		if (url == null) {
			return null;
		}
		
		final int jsessionPosition = url.indexOf(";jsessionid");
		if (jsessionPosition == -1) {
			return url;
		}

		final int questionMarkPosition = url.indexOf("?");
		if (questionMarkPosition < jsessionPosition) {
			return url.substring(0, url.indexOf(";jsessionid"));
		}
		return url.substring(0, jsessionPosition)+ url.substring(questionMarkPosition);
		
	}
}

  

  

  

原文地址:https://www.cnblogs.com/fron/p/jssessionid-20161130.html