Cleans up the usages of auth cookies. OWIN is in charge of auth cookies but because we have Webforms, WebApi, MVC and OWIN, they all like to deal with cookies differently. OWIN should still be solely in charge of the auth cookies, so the auth extensions are cleaned up, the renewal now works by queuing the renewal and we have custom middleware detect if a force renewal has been queued and we renew the auth cookie there. Have obsoleted a few methods that should not be used that write auth tickets directly (this is purely for backwards compat with webforms). All of these changes now ensure that the auth cookie is renewed consistently between Webforms, WebApi, MVC and OWIN. Some changes also include ensuring that OWIN is used to sign out.

This commit is contained in:
Shannon
2015-11-19 18:12:21 +01:00
parent 71ec09486d
commit 555b520a0c
21 changed files with 356 additions and 187 deletions

View File

@@ -0,0 +1,74 @@
using System.Net.Http;
using System.Security.Claims;
using System.Security.Principal;
using System.ServiceModel.Channels;
using System.Threading;
using System.Web;
using AutoMapper;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Security;
using Umbraco.Web.WebApi;
namespace Umbraco.Web.Security
{
internal static class WebAuthExtensions
{
/// <summary>
/// This will set a an authenticated IPrincipal to the current request given the IUser object
/// </summary>
/// <param name="request"></param>
/// <param name="user"></param>
/// <returns></returns>
internal static IPrincipal SetPrincipalForRequest(this HttpRequestMessage request, IUser user)
{
var principal = new ClaimsPrincipal(
new UmbracoBackOfficeIdentity(
new ClaimsIdentity(),
Mapper.Map<UserData>(user)));
//It is actually not good enough to set this on the current app Context and the thread, it also needs
// to be set explicitly on the HttpContext.Current !! This is a strange web api thing that is actually
// an underlying fault of asp.net not propogating the User correctly.
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
var http = request.TryGetHttpContext();
if (http)
{
http.Result.User = principal;
}
Thread.CurrentPrincipal = principal;
//For WebAPI
request.SetUserPrincipal(principal);
return principal;
}
/// <summary>
/// This will set a an authenticated IPrincipal to the current request given the IUser object
/// </summary>
/// <param name="httpContext"></param>
/// <param name="user"></param>
/// <returns></returns>
internal static IPrincipal SetPrincipalForRequest(this HttpContextBase httpContext, IUser user)
{
var principal = new ClaimsPrincipal(
new UmbracoBackOfficeIdentity(
new ClaimsIdentity(),
Mapper.Map<UserData>(user)));
//It is actually not good enough to set this on the current app Context and the thread, it also needs
// to be set explicitly on the HttpContext.Current !! This is a strange web api thing that is actually
// an underlying fault of asp.net not propogating the User correctly.
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
httpContext.User = principal;
Thread.CurrentPrincipal = principal;
return principal;
}
}
}