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