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):

cas的url中去掉jsessionid-LMLPHP

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);
    }

cas的url中去掉jsessionid-LMLPHP

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("\n");
}
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); }
}

  

  

  

05-01 03:11