using System;
using Microsoft.Owin.Security;
using Umbraco.Core.BackOffice;
namespace Umbraco.Web.Security
{
///
/// Custom secure format that ensures the Identity in the ticket is and not just a ClaimsIdentity
///
internal class UmbracoSecureDataFormat : ISecureDataFormat
{
private readonly int _loginTimeoutMinutes;
private readonly ISecureDataFormat _ticketDataFormat;
public UmbracoSecureDataFormat(int loginTimeoutMinutes, ISecureDataFormat ticketDataFormat)
{
_loginTimeoutMinutes = loginTimeoutMinutes;
_ticketDataFormat = ticketDataFormat ?? throw new ArgumentNullException(nameof(ticketDataFormat));
}
public string Protect(AuthenticationTicket data)
{
var backofficeIdentity = (UmbracoBackOfficeIdentity)data.Identity;
//create a new ticket based on the passed in tickets details, however, we'll adjust the expires utc based on the specified timeout mins
var ticket = new AuthenticationTicket(backofficeIdentity,
new AuthenticationProperties(data.Properties.Dictionary)
{
IssuedUtc = data.Properties.IssuedUtc,
ExpiresUtc = data.Properties.ExpiresUtc ?? DateTimeOffset.UtcNow.AddMinutes(_loginTimeoutMinutes),
AllowRefresh = data.Properties.AllowRefresh,
IsPersistent = data.Properties.IsPersistent,
RedirectUri = data.Properties.RedirectUri
});
return _ticketDataFormat.Protect(ticket);
}
///
/// Un-protects the cookie
///
///
///
public AuthenticationTicket Unprotect(string protectedText)
{
AuthenticationTicket decrypt;
try
{
decrypt = _ticketDataFormat.Unprotect(protectedText);
if (decrypt == null) return null;
}
catch (Exception)
{
return null;
}
if (!UmbracoBackOfficeIdentity.FromClaimsIdentity(decrypt.Identity, out var identity))
return null;
//return the ticket with a UmbracoBackOfficeIdentity
var ticket = new AuthenticationTicket(identity, decrypt.Properties);
return ticket;
}
}
}