zero authorize

This commit is contained in:
2020-04-15 14:09:52 +02:00
parent 9f5d9bb920
commit ccc63b9602
23 changed files with 389 additions and 97 deletions
+41 -18
View File
@@ -1,6 +1,8 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Raven.Client.Documents;
using Raven.Client.Documents.Session;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using zero.Core.Entities;
@@ -12,34 +14,50 @@ namespace zero.Core.Api
protected IHttpContextAccessor HttpContextAccessor { get; set; }
protected SignInManager<User> SignInManager { get; private set; }
public AuthenticationApi(IDocumentStore raven, IHttpContextAccessor httpContextAccessor)
public AuthenticationApi(IDocumentStore raven, IHttpContextAccessor httpContextAccessor, SignInManager<User> signInManager)
{
Raven = raven;
HttpContextAccessor = httpContextAccessor;
SignInManager = signInManager;
}
/// <inheritdoc />
public bool IsLoggedIn()
{
return HttpContextAccessor.HttpContext.User != null;
ClaimsPrincipal principal = HttpContextAccessor.HttpContext.User;
bool isAuthenticated = principal.Identity.IsAuthenticated;
bool isZeroUser = principal.HasClaim(Constants.Auth.Claims.IsZero, Constants.Auth.Claims.IsZero);
return isAuthenticated && isZeroUser;
}
/// <inheritdoc />
public async Task<bool> Login(string email, string password, bool isPersistent)
{
SignInResult result = await SignInManager.PasswordSignInAsync(email, password, isPersistent, true);
return result.Succeeded;
}
/// <inheritdoc />
public async Task Logout()
{
await SignInManager.SignOutAsync();
}
/// <inheritdoc />
public string GetUserId()
{
return null;
//ResolveIdFromClaimsPrincipal(HttpContextAccessor.HttpContext.User);
}
/// <inheritdoc />
public async Task<User> GetUser()
{
await Task.Delay(0);
return null;
ClaimsPrincipal principal = HttpContextAccessor.HttpContext.User;
return principal.Claims.FirstOrDefault(x => x.Type == Constants.Auth.Claims.UserId)?.Value;
}
}
@@ -51,14 +69,19 @@ namespace zero.Core.Api
/// </summary>
bool IsLoggedIn();
/// <summary>
/// Logs a zero-user in and sets cookie
/// </summary>
Task<bool> Login(string email, string password, bool isPersistent);
/// <summary>
/// Logs out the current user
/// </summary>
Task Logout();
/// <summary>
/// Get the ID of the currently logged in user
/// </summary>
string GetUserId();
/// <summary>
/// Get the currently logged-in user (or null if not logged in)
/// </summary>
Task<User> GetUser();
}
}
+67
View File
@@ -0,0 +1,67 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Raven.Client.Documents;
using System.Threading.Tasks;
using zero.Core.Entities;
namespace zero.Core.Api
{
public class UserApi : IUserApi
{
protected IDocumentStore Raven { get; private set; }
protected IHttpContextAccessor HttpContextAccessor { get; set; }
protected UserManager<User> UserManager { get; private set; }
public UserApi(IDocumentStore raven, IHttpContextAccessor httpContextAccessor, UserManager<User> userManager)
{
Raven = raven;
HttpContextAccessor = httpContextAccessor;
UserManager = userManager;
}
/// <inheritdoc />
public async Task<User> GetUser()
{
User user = await UserManager.GetUserAsync(HttpContextAccessor.HttpContext.User);
return user;
}
/// <inheritdoc />
public async Task<User> GetUserById(string id)
{
User user = await UserManager.FindByIdAsync(id);
return user;
}
/// <inheritdoc />
public async Task<User> GetUserByEmail(string email)
{
User user = await UserManager.FindByEmailAsync(email);
return user;
}
}
public interface IUserApi
{
/// <summary>
/// Get currently logged-in user
/// </summary>
Task<User> GetUser();
/// <summary>
/// Find user by id
/// </summary>
Task<User> GetUserById(string id);
/// <summary>
/// Find user by email
/// </summary>
Task<User> GetUserByEmail(string email);
}
}
+34 -18
View File
@@ -1,48 +1,64 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace zero.Core.Auth
{
public class ZeroAuthorizeAttribute : TypeFilterAttribute
{
public ZeroAuthorizeAttribute(string name) : base(typeof(ZeroAuthorizeFilter))
public ZeroAuthorizeAttribute() : this(String.Empty, true) { }
public ZeroAuthorizeAttribute(bool enabled) : this(String.Empty, enabled) { }
public ZeroAuthorizeAttribute(string name, bool enabled) : base(typeof(ZeroAuthorizeFilter))
{
Arguments = new object[] { name };
Arguments = new object[] { name, enabled };
}
}
public class ZeroAuthorizeFilter : AuthorizeFilter
public class ZeroAuthorizeFilter : IAuthorizationFilter
{
string Name { get; set; }
bool Enabled { get; set; }
public ZeroAuthorizeFilter(string name)
public ZeroAuthorizeFilter(string name, bool enabled) : base()
{
Name = name;
Enabled = enabled;
}
//public ZeroAuthorizeFilter(IAuthorizationPolicyProvider provider)
// : base(provider, new[] { new AuthorizeData(Constants.AzureAdPolicy) }) { }
public override async Task OnAuthorizationAsync(AuthorizationFilterContext context)
public void OnAuthorization(AuthorizationFilterContext context)
{
await Task.Delay(0);
//await base.OnAuthorizationAsync(context);
Console.WriteLine("zeroauthorize: " + (Name ?? "[empty]"));
Console.WriteLine("zeroauthorize: " + Name);
// allow anonymous skips all authorization
if (context.Filters.Any(item => item is IAllowAnonymousFilter) || !Enabled)
{
return;
}
context.Result = new AcceptedResult();
//context.Result = new ForbidResult();
//await base.OnAuthorizationAsync(context);
var httpContext = context.HttpContext;
var authService = httpContext.RequestServices.GetRequiredService<IAuthorizationService>();
//var username = context.HttpContext.User.Identity.Name;
ClaimsPrincipal user = context.HttpContext.User;
//Console.WriteLine($"{username} just logged in!");
bool isAuthenticated = user.Identity.IsAuthenticated;
bool isZeroUser = user.HasClaim(Constants.Auth.Claims.IsZero, Constants.Auth.Claims.IsZero);
if (!isAuthenticated || !isZeroUser)
{
context.Result = new StatusCodeResult(401);
}
}
}
}
+13
View File
@@ -7,6 +7,19 @@
public const string Scheme = "zeroCookies";
public const string CookieName = "zero.session";
public static class Claims
{
public const string IsZero = "zero.claim.iszero";
public const string UserId = "zero.claim.userid";
public const string UserName = "zero.claim.username";
public const string RoleId = "zero.claim.roleid";
public const string SecurityStamp = "zero.claim.securitystamp";
}
}
public static class Database
+6
View File
@@ -30,6 +30,12 @@ namespace zero.Core.Extensions
}
public static string EnsureSurroundedWith(this string input, char toSurroundWith)
{
return input.EnsureStartsWith(toSurroundWith).EnsureEndsWith(toSurroundWith);
}
public static string TrimEnd(this string value, string forRemoving)
{
if (String.IsNullOrEmpty(value)) return value;
+2 -2
View File
@@ -43,7 +43,7 @@ namespace zero.Core.Identity
/// <inheritdoc />
public Task SetEmailAsync(TUser user, string email, CancellationToken cancellationToken)
{
user.Email = email;
user.Email = email.ToLowerInvariant();
return Task.CompletedTask;
}
@@ -59,7 +59,7 @@ namespace zero.Core.Identity
/// <inheritdoc />
public Task SetNormalizedEmailAsync(TUser user, string normalizedEmail, CancellationToken cancellationToken)
{
user.Email = normalizedEmail;
user.Email = normalizedEmail.ToLowerInvariant();
return Task.CompletedTask;
}
}
+2 -2
View File
@@ -93,11 +93,11 @@ namespace zero.Core.Identity
/// <inheritdoc />
public Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken)
public async Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken)
{
using (IAsyncDocumentSession session = Raven.OpenAsyncSession())
{
return session.LoadAsync<TUser>(userId);
return await session.LoadAsync<TUser>(userId);
}
}