Make ICurrentPrincipalAccessor changeable.

Resolve #3913
pull/3918/head
maliming 5 years ago
parent cae569f9c3
commit 78664f1d49

@ -1,21 +1,28 @@
using Microsoft.AspNetCore.SignalR;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.SignalR
{
public class AbpSignalRUserIdProvider : IUserIdProvider, ITransientDependency
{
public ICurrentUser CurrentUser { get; }
public AbpSignalRUserIdProvider(ICurrentUser currentUser)
private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;
private readonly ICurrentUser _currentUser;
public AbpSignalRUserIdProvider(ICurrentPrincipalAccessor currentPrincipalAccessor, ICurrentUser currentUser)
{
CurrentUser = currentUser;
_currentPrincipalAccessor = currentPrincipalAccessor;
_currentUser = currentUser;
}
public virtual string GetUserId(HubConnectionContext connection)
{
return CurrentUser.Id?.ToString();
using (_currentPrincipalAccessor.Change(connection.User))
{
return _currentUser.Id?.ToString();
}
}
}
}

@ -1,18 +1,13 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.AspNetCore.Security.Claims
{
public class HttpContextCurrentPrincipalAccessor : ThreadCurrentPrincipalAccessor
{
public override ClaimsPrincipal Principal => _httpContextAccessor.HttpContext?.User ?? base.Principal;
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpContextCurrentPrincipalAccessor(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
CurrentScope.Value = () => httpContextAccessor.HttpContext?.User ?? GetThreadClaimsPrincipal();
}
}
}

@ -1,9 +1,12 @@
using System.Security.Claims;
using System;
using System.Security.Claims;
namespace Volo.Abp.Security.Claims
{
public interface ICurrentPrincipalAccessor
{
ClaimsPrincipal Principal { get; }
IDisposable Change(ClaimsPrincipal principal);
}
}

@ -1,11 +1,44 @@
using System.Security.Claims;
using System;
using System.Security.Claims;
using System.Threading;
using System.Xml.Schema;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Security.Claims
{
public class ThreadCurrentPrincipalAccessor : ICurrentPrincipalAccessor, ISingletonDependency
{
public virtual ClaimsPrincipal Principal => Thread.CurrentPrincipal as ClaimsPrincipal;
public Guid Id = Guid.NewGuid();
public virtual ClaimsPrincipal Principal
{
get => CurrentScope.Value?.Invoke();
set => CurrentScope.Value = () => value;
}
protected readonly AsyncLocal<Func<ClaimsPrincipal>> CurrentScope;
public ThreadCurrentPrincipalAccessor()
{
CurrentScope = new AsyncLocal<Func<ClaimsPrincipal>>
{
Value = GetThreadClaimsPrincipal
};
}
protected ClaimsPrincipal GetThreadClaimsPrincipal()
{
return Thread.CurrentPrincipal as ClaimsPrincipal;
}
public virtual IDisposable Change(ClaimsPrincipal principal)
{
var parentScope = Principal;
Principal = principal;
return new DisposeAction(() =>
{
Principal = parentScope;
});
}
}
}
}

@ -4,16 +4,19 @@ using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.AspNetCore.Mvc.Authorization
{
public class FakeAuthenticationMiddleware : IMiddleware, ITransientDependency
{
private readonly FakeUserClaims _fakeUserClaims;
private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;
public FakeAuthenticationMiddleware(FakeUserClaims fakeUserClaims)
public FakeAuthenticationMiddleware(FakeUserClaims fakeUserClaims, ICurrentPrincipalAccessor currentPrincipalAccessor)
{
_fakeUserClaims = fakeUserClaims;
_currentPrincipalAccessor = currentPrincipalAccessor;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
@ -24,9 +27,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Authorization
{
new ClaimsIdentity(_fakeUserClaims.Claims, "FakeSchema")
});
//_currentPrincipalAccessor.Change(context.User);
}
await next(context);
}
}
}
}

@ -0,0 +1,50 @@
using System.Collections.Generic;
using System.Security.Claims;
using Shouldly;
using Volo.Abp.Testing;
using Xunit;
namespace Volo.Abp.Security.Claims
{
public class CurrentPrincipalAccessor_Test : AbpIntegratedTest<AbpSecurityTestModule>
{
private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;
public CurrentPrincipalAccessor_Test()
{
_currentPrincipalAccessor = GetRequiredService<ICurrentPrincipalAccessor>();
}
[Fact]
public void Should_Get_Changed_Principal_If()
{
var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.Name,"bob"),
new Claim(ClaimTypes.NameIdentifier,"123456")
}));
var claimsPrincipal2 = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.Name,"lee"),
new Claim(ClaimTypes.NameIdentifier,"654321")
}));
_currentPrincipalAccessor.Principal.ShouldBe(null);
using (_currentPrincipalAccessor.Change(claimsPrincipal))
{
_currentPrincipalAccessor.Principal.ShouldBe(claimsPrincipal);
using (_currentPrincipalAccessor.Change(claimsPrincipal2))
{
_currentPrincipalAccessor.Principal.ShouldBe(claimsPrincipal2);
}
_currentPrincipalAccessor.Principal.ShouldBe(claimsPrincipal);
}
_currentPrincipalAccessor.Principal.ShouldBeNull();
}
}
}
Loading…
Cancel
Save