using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Owin.Security;
using Umbraco.Core;
namespace Umbraco.Web.Security
{
public static class AuthenticationManagerExtensions
{
private static ExternalLoginInfo GetExternalLoginInfo(AuthenticateResult result)
{
if (result == null || result.Identity == null)
{
return null;
}
var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier);
if (idClaim == null)
{
return null;
}
// By default we don't allow spaces in user names
var name = result.Identity.Name;
if (name != null)
{
name = name.Replace(" ", "");
}
var email = result.Identity.FindFirst(ClaimTypes.Email)?.Value;
return new ExternalLoginInfo
{
ExternalIdentity = result.Identity,
Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value, idClaim.Issuer),
DefaultUserName = name,
Email = email
};
}
///
/// Extracts login info out of an external identity
///
///
///
/// key that will be used to find the userId to verify
///
/// the value expected to be found using the xsrfKey in the AuthenticationResult.Properties
/// dictionary
///
///
public static async Task GetExternalLoginInfoAsync(this IAuthenticationManager manager,
string authenticationType,
string xsrfKey, string expectedValue)
{
if (manager == null)
{
throw new ArgumentNullException("manager");
}
var result = await manager.AuthenticateAsync(authenticationType);
// Verify that the userId is the same as what we expect if requested
if (result != null &&
result.Properties != null &&
result.Properties.Dictionary != null &&
result.Properties.Dictionary.ContainsKey(xsrfKey) &&
result.Properties.Dictionary[xsrfKey] == expectedValue)
{
return GetExternalLoginInfo(result);
}
return null;
}
///
/// Extracts login info out of an external identity
///
///
///
///
public static async Task GetExternalLoginInfoAsync(this IAuthenticationManager manager, string authenticationType)
{
if (manager == null)
{
throw new ArgumentNullException("manager");
}
return GetExternalLoginInfo(await manager.AuthenticateAsync(authenticationType));
}
public static IEnumerable GetExternalAuthenticationTypes(this IAuthenticationManager manager)
{
if (manager == null) throw new ArgumentNullException(nameof(manager));
return manager.GetAuthenticationTypes(d => d.Properties != null && d.Properties.ContainsKey("Caption"));
}
public static ClaimsIdentity CreateTwoFactorRememberBrowserIdentity(this IAuthenticationManager manager, string userId)
{
if (manager == null) throw new ArgumentNullException(nameof(manager));
var rememberBrowserIdentity = new ClaimsIdentity(Constants.Web.TwoFactorRememberBrowserCookie);
rememberBrowserIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId));
return rememberBrowserIdentity;
}
}
public class ExternalLoginInfo
{
/// Associated login data
public UserLoginInfo Login { get; set; }
/// Suggested user name for a user
public string DefaultUserName { get; set; }
/// Email claim from the external identity
public string Email { get; set; }
/// The external identity
public ClaimsIdentity ExternalIdentity { get; set; }
}
}