Permalink
Browse files

Re-factor SecureOnly Cookie

  • Loading branch information...
1 parent 5d7a836 commit 09a57932dea48c1b075962359384e075f98e4b07 @mythz mythz committed Feb 14, 2013
@@ -3,12 +3,11 @@
namespace ServiceStack.ServiceHost
{
- public interface ICookies
- {
- void DeleteCookie(string cookieName);
- void AddCookie(Cookie cookie);
- void AddPermanentCookie(string cookieName, string cookieValue);
- void AddSessionCookie(string cookieName, string cookieValue);
- void AddSessionCookie(string cookieName, string cookieValue, bool secureCookieAsRequest);
- }
+ public interface ICookies
+ {
+ void DeleteCookie(string cookieName);
+ void AddCookie(Cookie cookie);
+ void AddPermanentCookie(string cookieName, string cookieValue, bool? secureOnly = null);
+ void AddSessionCookie(string cookieName, string cookieValue, bool? secureOnly = null);
+ }
}
@@ -81,7 +81,8 @@ public static string CreatePermanentSessionId(this IHttpResponse res, IHttpReque
public static string CreateTemporarySessionId(this IHttpResponse res, IHttpRequest req)
{
var sessionId = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
- res.Cookies.AddSessionCookie(SessionFeature.SessionId, sessionId, (EndpointHostConfig.Instance.AllowCookieSecureAsRequest && req.IsSecureConnection));
+ res.Cookies.AddSessionCookie(SessionFeature.SessionId, sessionId,
+ (EndpointHost.Config.OnlySendSessionCookiesSecurely && req.IsSecureConnection));
req.Items[SessionFeature.SessionId] = sessionId;
return sessionId;
}
@@ -1,104 +1,102 @@
using System;
-using System.Collections.Generic;
-using System.Globalization;
using System.Net;
-using System.Text;
using System.Web;
using ServiceStack.Common.Web;
namespace ServiceStack.ServiceHost
{
- public class Cookies : ICookies
- {
- readonly IHttpResponse httpRes;
- private static readonly DateTime Session = DateTime.MinValue;
- private static readonly DateTime Permanent = DateTime.UtcNow.AddYears(20);
- private const string RootPath = "/";
+ public class Cookies : ICookies
+ {
+ readonly IHttpResponse httpRes;
+ private static readonly DateTime Session = DateTime.MinValue;
+ private static readonly DateTime Permanent = DateTime.UtcNow.AddYears(20);
+ private const string RootPath = "/";
- public Cookies(IHttpResponse httpRes)
- {
- this.httpRes = httpRes;
- }
+ public Cookies(IHttpResponse httpRes)
+ {
+ this.httpRes = httpRes;
+ }
- /// <summary>
- /// Sets a persistent cookie which never expires
- /// </summary>
- public void AddPermanentCookie(string cookieName, string cookieValue)
- {
- AddCookie(new Cookie(cookieName, cookieValue, RootPath) {
- Expires = Permanent,
- });
- }
+ /// <summary>
+ /// Sets a persistent cookie which never expires
+ /// </summary>
+ public void AddPermanentCookie(string cookieName, string cookieValue, bool? secureOnly = null)
+ {
+ var cookie = new Cookie(cookieName, cookieValue, RootPath) {
+ Expires = Permanent,
+ };
+ if (secureOnly != null)
+ {
+ cookie.Secure = secureOnly.Value;
+ }
+ AddCookie(cookie);
+ }
- /// <summary>
- /// Sets a session cookie which expires after the browser session closes
- /// </summary>
- public void AddSessionCookie(string cookieName, string cookieValue)
- {
- this.AddSessionCookie(cookieName, cookieValue, false);
- }
- /// <summary>
- /// Sets a session cookie which expires after the browser session closes
- /// </summary>
- public void AddSessionCookie(string cookieName, string cookieValue, bool secureCookieAsRequest)
- {
- var __newCookie = new Cookie(cookieName, cookieValue, RootPath);
- __newCookie.Secure = secureCookieAsRequest;
- this.AddCookie(__newCookie);
- }
+ /// <summary>
+ /// Sets a session cookie which expires after the browser session closes
+ /// </summary>
+ public void AddSessionCookie(string cookieName, string cookieValue, bool? secureOnly = null)
+ {
+ var cookie = new Cookie(cookieName, cookieValue, RootPath);
+ if (secureOnly != null)
+ {
+ cookie.Secure = secureOnly.Value;
+ }
+ this.AddCookie(cookie);
+ }
- /// <summary>
- /// Deletes a specified cookie by setting its value to empty and expiration to -1 days
- /// </summary>
- public void DeleteCookie(string cookieName)
- {
- var cookie = new Cookie(cookieName, string.Empty, "/") {
- Expires = DateTime.UtcNow.AddDays(-1)
- };
- AddCookie(cookie);
- }
+ /// <summary>
+ /// Deletes a specified cookie by setting its value to empty and expiration to -1 days
+ /// </summary>
+ public void DeleteCookie(string cookieName)
+ {
+ var cookie = new Cookie(cookieName, string.Empty, "/") {
+ Expires = DateTime.UtcNow.AddDays(-1)
+ };
+ AddCookie(cookie);
+ }
- public HttpCookie ToHttpCookie(Cookie cookie)
- {
- var httpCookie = new HttpCookie(cookie.Name, cookie.Value) {
- Path = cookie.Path,
- Expires = cookie.Expires,
- HttpOnly = true,
- Secure = cookie.Secure
- };
- if (string.IsNullOrEmpty(httpCookie.Domain))
- {
- httpCookie.Domain = (string.IsNullOrEmpty(cookie.Domain) ? null : cookie.Domain);
- }
- return httpCookie;
- }
+ public HttpCookie ToHttpCookie(Cookie cookie)
+ {
+ var httpCookie = new HttpCookie(cookie.Name, cookie.Value) {
+ Path = cookie.Path,
+ Expires = cookie.Expires,
+ HttpOnly = true,
+ Secure = cookie.Secure
+ };
+ if (string.IsNullOrEmpty(httpCookie.Domain))
+ {
+ httpCookie.Domain = (string.IsNullOrEmpty(cookie.Domain) ? null : cookie.Domain);
+ }
+ return httpCookie;
+ }
- public string GetHeaderValue(Cookie cookie)
- {
- return cookie.Expires == Session
- ? String.Format("{0}={1};path=/", cookie.Name, cookie.Value)
- : String.Format("{0}={1};expires={2};path={3}",
- cookie.Name, cookie.Value, cookie.Expires.ToString("R"), cookie.Path ?? "/");
- }
+ public string GetHeaderValue(Cookie cookie)
+ {
+ return cookie.Expires == Session
+ ? String.Format("{0}={1};path=/", cookie.Name, cookie.Value)
+ : String.Format("{0}={1};expires={2};path={3}",
+ cookie.Name, cookie.Value, cookie.Expires.ToString("R"), cookie.Path ?? "/");
+ }
- /// <summary>
- /// Sets a persistent cookie which expires after the given time
- /// </summary>
- public void AddCookie(Cookie cookie)
- {
- var aspNet = this.httpRes.OriginalResponse as HttpResponse;
- if (aspNet != null)
- {
- var httpCookie = ToHttpCookie(cookie);
- aspNet.SetCookie(httpCookie);
- return;
- }
- var httpListener = this.httpRes.OriginalResponse as HttpListenerResponse;
- if (httpListener != null)
- {
- var cookieStr = GetHeaderValue(cookie);
- httpListener.Headers.Add(HttpHeaders.SetCookie, cookieStr);
- }
- }
- }
+ /// <summary>
+ /// Sets a persistent cookie which expires after the given time
+ /// </summary>
+ public void AddCookie(Cookie cookie)
+ {
+ var aspNet = this.httpRes.OriginalResponse as HttpResponse;
+ if (aspNet != null)
+ {
+ var httpCookie = ToHttpCookie(cookie);
+ aspNet.SetCookie(httpCookie);
+ return;
+ }
+ var httpListener = this.httpRes.OriginalResponse as HttpListenerResponse;
+ if (httpListener != null)
+ {
+ var cookieStr = GetHeaderValue(cookie);
+ httpListener.Headers.Add(HttpHeaders.SetCookie, cookieStr);
+ }
+ }
+ }
}
@@ -96,6 +96,7 @@ public static EndpointHostConfig Instance
CustomHttpHandlers = new Dictionary<HttpStatusCode, IServiceStackHttpHandler>(),
GlobalHtmlErrorHttpHandler = null,
MapExceptionToStatusCode = new Dictionary<Type, int>(),
+ OnlySendSessionCookiesSecurely = false,
DefaultJsonpCacheExpiration = new TimeSpan(0, 20, 0),
MetadataVisibility = EndpointAttributes.Any,
Return204NoContentForEmptyResponse = true,
@@ -155,6 +156,7 @@ public EndpointHostConfig()
this.CustomHttpHandlers = instance.CustomHttpHandlers;
this.GlobalHtmlErrorHttpHandler = instance.GlobalHtmlErrorHttpHandler;
this.MapExceptionToStatusCode = instance.MapExceptionToStatusCode;
+ this.OnlySendSessionCookiesSecurely = instance.OnlySendSessionCookiesSecurely;
this.DefaultJsonpCacheExpiration = instance.DefaultJsonpCacheExpiration;
this.MetadataVisibility = instance.MetadataVisibility;
this.Return204NoContentForEmptyResponse = Return204NoContentForEmptyResponse;
@@ -399,6 +401,8 @@ public EndpointAttributes MetadataVisibility
public IServiceStackHttpHandler GlobalHtmlErrorHttpHandler { get; set; }
public Dictionary<Type, int> MapExceptionToStatusCode { get; set; }
+ public bool OnlySendSessionCookiesSecurely { get; set; }
+
public TimeSpan DefaultJsonpCacheExpiration { get; set; }
public bool Return204NoContentForEmptyResponse { get; set; }
@@ -418,14 +422,7 @@ public string DefaultOperationNamespace
this.defaultOperationNamespace = value;
}
}
- private const string SecureCookieAsRequest = "ss:Cookie:SecureAsRequest";
- public bool AllowCookieSecureAsRequest
- {
- get
- {
- return ConfigUtils.GetAppSetting<bool>(EndpointHostConfig.SecureCookieAsRequest, false);
- }
- }
+
private string GetDefaultNamespace()
{
if (!String.IsNullOrEmpty(this.defaultOperationNamespace)

0 comments on commit 09a5793

Please sign in to comment.