1

Is there any way to access authentication state outside Component ? For example I am trying ,

 public class ServersideCurrentUserIdentityProvider : ICurrentUserIdentityProvider, IDisposable
    {
        private Task<AuthenticationState> currentAuthenticationStateTask;
        private readonly AuthenticationStateProvider stateProvider;

        public ServersideCurrentUserIdentityProvider(AuthenticationStateProvider stateProvider)
        {
            this.stateProvider = stateProvider;
            stateProvider.AuthenticationStateChanged += OnAuthenticationStateChanged;
            currentAuthenticationStateTask = stateProvider.GetAuthenticationStateAsync();
        }

        private void OnAuthenticationStateChanged(Task<AuthenticationState> task)
        {
            this.currentAuthenticationStateTask = task;
        }

        public async Task<ClaimsPrincipal> GetCurrentUserPrincipal()
        {
            var state = await currentAuthenticationStateTask;
            return state.User;
        }

        public void Dispose()
        {
            this.stateProvider.AuthenticationStateChanged -= OnAuthenticationStateChanged;
        }
    }

this class is registered in DI as

services.AddServerSideBlazor();
services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<ApplicationUser>>();
services.AddSingletone<ICurrentUserIdentityProvider,ServersideCurrentUserIdentityProvider>()

I am trying to use CurrentUserProvider as a Parameter to db Context as

public class ExampleDbContext()
{
 public ExampleDbContext(DbContextOption opt, ICurrentUserProvider provider){

  override Task<int> onSaveChange(){
var principal=  await this.userProvider.GetCurrentPrincipal();
foreach .. 
entity.CreatedBy=principal.Name;
}
}

When I try to run, I get exception Saying, GetAuthenticationState Should be called After SetAuthentication State, How do I do that ???

crypted
  • 10,118
  • 3
  • 39
  • 52
  • You're seeing the exception during startup because the constructor for the database will run every time the DB context is called. It will be called even before your user has a chance to log in. So, therefore, you can't depend on services in your DbContext and you need to handle the fact that there might not be a user associated with the request. That means skipping the GetCurrentPrincipal call. – Dennis VW Dec 31 '19 at 02:07
  • thats not actually correct. – crypted Jan 01 '20 at 12:31
  • @crypted did you found a solution for that? trying to do something similiar... – JoeGER94 Jan 20 '21 at 08:26

1 Answers1

0

Personally, I lean towards setting any "CreatedBy"/"DateCreated"/etc properties of Entities in whatever business logic is responsible for cooking them up in the first place.

Having said that, what happens if you just put AuthenticationStateProvider into the ExampleDbContext constructor? Wouldn't it be resolved along with the DbContext when calling it, and allow you to figure out the resolving (calling) user, if present at all?

JohannSig
  • 131
  • 2
  • 8