Error while validating the service descriptor - c#

I am trying to add a handler to my services in Startup.cs. Doing this will give me the following error:
Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Authorization.IAuthorizationService Lifetime: Transient ImplementationType: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService': Unable to resolve service for type 'Microsoft.AspNetCore.Http.IHttpContextAccessor' while attempting to activate 'ApiPortal.Classes.PolicyAuthorizationHandler')
Here is my Startup.cs ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));
services.Configure<OpenIdConnectOptions>("azure", options =>
{
var existingOnTokenValidatedHandler = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
await existingOnTokenValidatedHandler(context);
await context.HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme, context.Principal);
};
var existingOnUserInformationReceived = options.Events.OnUserInformationReceived;
options.Events.OnUserInformationReceived = async context =>
{
await existingOnUserInformationReceived(context);
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("AzureAccount", policy_builder => policy_builder.AddRequirements(new PolicyRequirement()));
});
services.AddScoped<IAuthorizationHandler, PolicyAuthorizationHandler>();
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddRazorPages()
.AddMicrosoftIdentityUI();
}
Here is my PolicyAuthorizationHandler.cs:
public class PolicyAuthorizationHandler : AuthorizationHandler<PolicyRequirement>
{
readonly IHttpContextAccessor _contextAccessor;
public PolicyAuthorizationHandler(IHttpContextAccessor ca)
{
_contextAccessor = ca;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PolicyRequirement requirement)
{
if (context.Resource is AuthorizationFilterContext filterContext)
{
var area = "";
var controller = (filterContext.RouteData.Values["controller"] as string)?.ToLower();
var action = (filterContext.RouteData.Values["action"] as string)?.ToLower();
var id = "";
if (await requirement.Pass(context, _contextAccessor, area, controller, action, id))
{
context.Succeed(requirement);
}
}
if (context.Resource is DefaultHttpContext httpContext)
{
var area = "";
var controller = httpContext.Request.RouteValues["controller"].ToString();
var action = httpContext.Request.RouteValues["action"].ToString();
var id = "";
if (await requirement.Pass(context, _contextAccessor, area, controller, action, id))
{
context.Succeed(requirement);
}
}
}
}
Here is my PolicyRequirement.cs class:
public class PolicyRequirement : IAuthorizationRequirement
{
IHttpContextAccessor _contextAccessor;
AuthorizationHandlerContext _context;
public async Task<bool> Pass(AuthorizationHandlerContext context, IHttpContextAccessor contextAccessor, string area, string controller, string action, string id)
{
_context = context;
_contextAccessor = contextAccessor;
bool authorized = false;
//authorization logic goes here
string email = contextAccessor.HttpContext.User.Identity.Name;
if (email == "myemail#email.com") authorized = true;
return await Task.FromResult(authorized);
}
}
I have already tried changing services.AddScoped<IAuthorizationHandler, PolicyAuthorizationHandler>() to services.AddTransient<IAuthorizationHandler, PolicyAuthorizationHandler>() and services.AddSingleton<IAuthorizationHandler, PolicyAuthorizationHandler>(). These don't seem to work.
I have also taken a look at this and this thread, but I can't seem to find a solution for my problem here as well.
What am I doing wrong and what can I do to fix this error? Thanks in advance.

This error means that PolicyAuthorizationHandler class depends on a service of type IHttpContextAccessor, but that service is not registered in the service container.
you need to register IHttpContextAccessor in ConfigureServices by adding line services.AddHttpContextAccessor();
and after this, you can pass IHttpContextAccessor to the constructor of PolicyAuthorizationHandler
`

Related

Microsoft.AspNetCore.Identity in Blazor UserManager and RoleManager always null

I am trying to get a users Roles after they log in via Single Sign On. The problem is that the UserManager and RoleManager objects are always null. From what I have read online, is seems like these objects should be created via injection, but I am not sure what I am doing wrong. Here is my code (if I am missing anything relevant, please let me know and I will edit my question). I also did not see a tag for "Microsoft.AspNetCore.Identity" so apologies if this is not tagged correctly (the error is in the last function "TransformClaims"):
Startup.cs
using Microsoft.AspNetCore.Identity;
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//.....
app.UseAuthentication();
app.UseAuthorization();
//.....
}
public void ConfigureServices(IServiceCollection services)
{
//.....
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("ApplicationDbContextConnection")));
services.AddIdentity<CustomUserContext, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.Configure<IdentityOptions>(options =>
options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<CustomUserContext>>();
services.AddAuthorizationCore();
ConfigureSSO(services);
services.AddTransient<UserManager<USAIDUserContext>>();
services.AddTransient<ApplicationDbContext>();
//.....
}
public void ConfigureSSO(IServiceCollection services){
//code to provide SSO
//relevant code is when SSO returns token validation
OnTokenValidated = async ctxt =>
{
Trace.TraceInformation("Token validated");
ctxt.Properties.IsPersistent = true;
ctxt.Properties.IssuedUtc = DateTime.Now;
ctxt.Properties.ExpiresUtc = DateTime.Now.AddDays(1);
ClaimsPrincipal claimPrinciple = ctxt.Principal;
ClaimsIdentity ClaimsID = await TransformClaims(claimPrinciple);
await Task.Yield();
},
}
private async Task<ClaimsIdentity> TransformClaims(ClaimsPrincipal principal)
{
ClaimsIdentity appIdentity = null;
if(principal == null)
{
throw new ArgumentNullException(nameof(principal));
}
else
{
//gets loggedin email, which is stored in database
var loggedInUserId = principal.Claims.FirstOrDefault(c => c.Type == "email")?.Value;
RoleManager<IdentityRole> _rolemanager;
UserManager<CustomUserContext> _userManager;
//both RoleManager and UserManager are null, causing the functions below to have an error about object being null
var user = await _userManager.FindByEmailAsync(loggedInUserId);
var roles = await _userManager.GetRolesAsync(user);
}
return appIdentity;
}
Edit
AddRolesClaimsTransformation.cs
public class AddRolesClaimsTransformation : IClaimsTransformation
{
private readonly IUserService _userService;
public AddRolesClaimsTransformation(IUserService userService)
{
_userService = userService;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
// Code Never Hit
var clone = principal.Clone();
var newIdentity = (ClaimsIdentity)clone.Identity;
// Support AD and local accounts
var nameId = principal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier ||
c.Type == ClaimTypes.Name);
if (nameId == null)
{
return principal;
}
// Get user from database
var userResponse = await _userService.GetAsync(nameId.Value);
return clone;
}
}
public interface IUserService
{
Task<USAIDUserContext> GetAsync(string id);
}
}
This is my implementation, you can find the constructor of the class that implement the interface.
I've injected IUserService and inside the constructor of UserService class I've added injection for UserManager and RoleManager.
public class AddRolesClaimsTransformation : IClaimsTransformation
{
private readonly IUserService _userService;
public AddRolesClaimsTransformation(IUserService userService)
{
_userService = userService;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
// Clone current identity
var clone = principal.Clone();
var newIdentity = (ClaimsIdentity)clone.Identity;
// Support AD and local accounts
var nameId = principal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier ||
c.Type == ClaimTypes.Name);
if (nameId == null)
{
return principal;
}
// Get user from database
var userResponse = await _userService.GetAsync(nameId.Value);
if (!userResponse.Succeeded || userResponse.Data is null)
{
return principal;
}
var user = userResponse.Data;
var rolesResponse = await _userService.GetRolesAsync(user.Id);
...
return clone;
}
}
This is an example of a method inside UserService:
public async Task<IResult<UserResponse>> GetAsync(string userId)
{
var user = await _userManager.Users.Where(u => u.Id.ToString() == userId).FirstOrDefaultAsync();
var result = _mapper.Map<UserResponse>(user);
return await Result<UserResponse>.SuccessAsync(result);
}

Cannot access a disposed object.\r\nObject name: 'UserManager`1 - while calling CreateAsync(user, model.password)

I am working on .net core porject.
My Project structure has 4 projects.
Student_Database - (Contains Database table model and ApplicatinDBContext)
Student_Entities - (Contains All the View side models)
Student_Service - (All the Database operation handling from here. It is connected to Database.
ex: IUserService and UserService)
Student_Web - ( Controllers and all the methods, logic along with all the views are in this project)
I have implemented Entity Framework core. And try to using Usermanager for insert data.
Now when I am calling method "CreateAsync" from controller(Student_Web) it works fine and user inserted.
But I want to implement database operation in Student_Service. So when I am calling "CreateAsync" from UserService it gives me error "Cannot access a disposed object.\r\nObject name: 'UserManager`1"
I am calling this interface IUserService from controller. So here is my code in UserService.
Please help me to solve this.
public class UserService : IUserService
{
#region Properties
private readonly IDbContext _context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<IdentityRole<int>> _roleManager;
#endregion
#region Consturctor
public UserService(
IDbContext context
, UserManager<ApplicationUser> userManager
, RoleManager<IdentityRole<int>> roleManager
{
_context = context;
_userManager = userManager;
_roleManager = roleManager;
}
#endregion
#region Methods
public async Task<bool> Create(NewUsers model)
{
bool result = false;
try
{
var user = await _userManager.FindByNameAsync(model.UserName);
if (user == null)
{
model.Password = GeneratePassword();
user = new ApplicationUser
{
//Id = 10,
UserName = model.UserName,
Email = model.UserName,
AccessFailedCount = 0,
FirstName = model.FirstName,
LastName = model.LastName,
CreatedBy = 2,
CreatedDate = DateTime.UtcNow,
Active = false
};
var returnResult = await _userManager.CreateAsync(user, model.Password);
if (returnResult.Succeeded)
{
returnResult = await _userManager.AddToRoleAsync(user, _roleManager.Roles.Where(x=>x.Id == model.RoleId).Select(x => x.Name).FirstOrDefault());
}
if (model.CompanyId!= null)
{
foreach (var item in model.CompanyId)
{
var userMap = new UserCompanyMapping();
userMap.UserId = user.Id;
userMap.CompanyId = item;
_userCompanyMappingRepository.Insert(userMap);
}
}
result = returnResult.Succeeded;
}
}
catch (Exception ex)
{
return false;
}
return result;
}
#endregion
}
//startup class
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(option =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
option.Filters.Add(new AuthorizeFilter(policy));
});
services.AddDbContextPool<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentityCore<ApplicationUser>();
// Register Dependencies extra service
services.AddAppServices();
services.AddIdentity<ApplicationUser, IdentityRole<int>>(options =>
{
options.User.RequireUniqueEmail = true;
options.Password.RequireNonAlphanumeric = false;
})
.AddRoles<IdentityRole<int>>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(option =>
{
option.LoginPath = "/login";
option.AccessDeniedPath = "/Login/AccessDenied";
});
// Register dependancy
RegisterAutoMapper(services);
RegisterServices(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.ConfigureRequestPipeline();
app.UseStaticFiles();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//register all routes
EngineContext.Current.Resolve<IRoutePublisher>().RegisterRoutes(endpoints);
});
//app.UseEndpoints(endpoints =>
//{
// endpoints.MapControllerRoute(
// name: "default",
// pattern: "{controller=Login}/{action=Index}/{id?}");
//});
}
private void RegisterServices(IServiceCollection services)
{
// Get class libraryGetAssembly(ty)
var serviceLibraries = Assembly.Load("Student.Services")
.GetTypes()
.Where(x => x.IsClass && x.GetInterfaces().Any() && x.Namespace.Contains(".Services.Services"))
.ToList();
if (serviceLibraries != null && serviceLibraries.Count > 0)
{
foreach (var service in serviceLibraries)
{
var interfaceType = service.GetInterfaces().FirstOrDefault();
services.AddScoped(interfaceType, service);
}
}
}
private void RegisterAutoMapper(IServiceCollection services)
{
// Auto Mapper Configurations
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new MappingProfile());
});
IMapper mapper = mappingConfig.CreateMapper();
services.AddSingleton(mapper);
}
}
//Action controller method
namespace Student.Web.Controllers
{
[Authorize]
public class UserController : Controller
{
private readonly IUserService userService;
private readonly ICommonService commonService;
public UserController(
IUserService userService,
ICommonService commonService)
{
this.userService = userService;
this.commonService = commonService;
}
public IActionResult Index()
{
return View();
}
[HttpGet]
public IActionResult Create()
{
ViewBag.RoleList = commonService.GetRoles().Result;
ViewBag.CompanyList = commonService.GetCompanies().Result;
ViewBag.CityList = commonService.GetCities().Result;
ViewBag.CompanyAccessList = commonService.GetCompanyAccessListMultiCheck().Result;
return View();
}
[HttpPost]
public IActionResult Create(UserAddModel model)
{
if (ModelState.IsValid)
{
var response = userService.Create(model);
}
return RedirectToAction("Index");
}
}
}
The call to your service is never awaited, so it is kind of became fire-and-forget which means the request might ends before the service finishes its job which would cause the requested services to get disposed.
To fix that you need to alter your Create Action a little bit by doing the followings:
Make your action async and let it return Task<IActionResult>.
Await the service.
[HttpPost]
public async Task<IActionResult> Create(UserAddModel model)
{
if (ModelState.IsValid)
{
var response = await userService.Create(model);
}
return RedirectToAction("Index");
}
Then it should work just fine.

asp.net core - Integration test and view components

I'm facing a strange issue since I created a view component in my app.
All my integration tests using an HttpClient start failing with response code "Internal Server Error".
Here the test configuration :
public class BaseTest<TStartup>
: WebApplicationFactory<TStartup> where TStartup : class
{
private readonly bool _hasUser;
private readonly HttpClient _client;
protected BaseTest(bool hasUser = false)
{
_hasUser = hasUser;
_client = CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false,
});
}
protected async Task<HttpResponseMessage> GetPageByPath(string path)
{
return await _client.GetAsync(path);
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureTestServices(services =>
{
if (_hasUser)
{
services.AddScoped<IAuthenticationService, AuthenticationServiceStub>();
services.AddSingleton<IStartupFilter, FakeUserFilter>();
services.AddMvc(options =>
{
options.Filters.Add(new AllowAnonymousFilter());
options.Filters.Add(new AuthenticatedAttribute());
});
}
});
builder.ConfigureServices(services =>
{
// Create a new service provider.
ServiceProvider serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
// Build the service provider.
var sp = services.BuildServiceProvider();
// Create a scope to obtain a reference to the database
// context (ApplicationDbContext).
using (var scope = sp.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var logger = scopedServices
.GetRequiredService<ILogger<BaseTest<TStartup>>>();
}
});
}
}
}
And a usage example :
public class BasicTest : BaseTest<Startup>
{
public BasicTest() : base()
{
}
[Theory]
[InlineData("/")]
[InlineData("/Index")]
[InlineData("/Users/SignOut")]
[Trait("Category", "Integration")]
public async Task Get_EndpointsReturnSuccessAndCorrectContentType(string url)
{
// Act
var response = await GetPageByPath(url);
// Assert
response.EnsureSuccessStatusCode(); // Status Code 200-299
Assert.Equal("text/html; charset=utf-8",
response.Content.Headers.ContentType.ToString());
}
}
If you need the component code let me know.
I already rollback code to check when this start happening, and it's start after the commit with the new Component called in several pages.

'System.InvalidOperationException' occurred in System.Private.CoreLib.dll but was not handled in user code

I am using a dependency injection to access information that is in the session of my application through a class (component), but when doing access ends up giving the error: "An exception of type 'System.InvalidOperationException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'Session has not been configured for this application or request.'"
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddSessionStateTempDataProvider();
//Adiciona uma implementação padrão na memória do IDistributedCache.
services.AddDistributedMemoryCache();
//Session
services.AddSession(options =>
{
//Set a short timeout for easy testing.
options.IdleTimeout = TimeSpan.FromMinutes(60);
options.Cookie.HttpOnly = true;
//Make the session cookie essential
options.Cookie.IsEssential = true;
});
services.AddHttpContextAccessor();
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//Adicionar os filtros nos controllers
services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
//adicionado por instância
options.Filters.Add(new CustomActionFilter());
options.Filters.Add(new CustomAsyncActionFilter());
//adicionado por tipo
options.Filters.Add(typeof(CustomActionFilter));
options.Filters.Add(typeof(CustomAsyncActionFilter));
});
//Injeção de Dependência
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<Common.AtualizarFiltros.IRefreshPF, Common.AtualizarFiltros.RefreshPF>();
}
MyController.cs
public class PessoaFisicaController : Controller
{
private readonly IRefreshPF _refreshPF;
public PessoaFisicaController(IRefreshPF refreshPF)
{
_refreshPF = refreshPF;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async void AddOrRemoveSexo([FromBody] Models.Json.JsonJsonAddOrRemoveSexo jsonInput)
{
await _refreshPF.AddOrRemoveSexoAsync(jsonInput);
}
}
MyClass.cs
public interface IRefreshPF
{
Task AddOrRemoveSexoAsync(Models.Json.JsonJsonAddOrRemoveSexo jsonInput);
}
public class RefreshPF : IRefreshPF
{
private readonly IHttpContextAccessor _context;
public RefreshPF(IHttpContextAccessor context)
{
_context = context;
}
public async Task AddOrRemoveSexoAsync(Models.Json.JsonJsonAddOrRemoveSexo jsonInput)
{
int idSexo = 0;
//Modelos
Model.SqlServer.Segmentacao.Sexo sexo = new Model.SqlServer.Segmentacao.Sexo();
Models.Session.SessionResumoContagem sessionResumoContagem = new Models.Session.SessionResumoContagem();
string[] array = jsonInput.id.Split('_');
idSexo = int.Parse(array[1]);
sexo = await Service.Filtros.GetByIdSexoAsync(idSexo);
sessionResumoContagem = _context.HttpContext.Session.Get<Models.Session.SessionResumoContagem>("ResumoContagem");
if (sessionResumoContagem == null)
{
sessionResumoContagem = new Models.Session.SessionResumoContagem();
sessionResumoContagem.tipoPessoa = (int)Model.Enumeradores.TipoPessoa.PessoaFisica;
_context.HttpContext.Session.Set<Models.Session.SessionResumoContagem>("ResumoContagem", sessionResumoContagem);
}
if (sessionResumoContagem.sexos == null)
{
sessionResumoContagem.sexos = new List<Model.SqlServer.Segmentacao.Sexo>();
}
}
}
Error occurs in sessionResumoContagem = _context.HttpContext.Session.Get("ResumoContagem");
Can anyone help?
'Session has not been configured for this application or request.'"
Typically, this error happens when you access the HttpContext.Session object while never registering the Session middleware before.
Make sure the .UseSession() is invoked:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseSession();
...
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Also, be aware the UseSession() must be invoked before you use HttpContext.Session. At least, make sure it is invoked before UseMvc().

AuthorizeAttribute on BaseController HttpContext.User.Identity.Name in policy missing

In my asp.net core Web API i want to be sure that Users actually exist and are not deactivated when calling some Actions. We use JwtBearer authentication what works pretty fine. Our problem is that using only the Microsoft.AspNetCore.Authorization.AuthorizeAttribute it won't matter, if a user was deleted or deactivated after the token was issued (as long as the token it self is valid).
In my Startup.cs i configured a policy to solve this issue:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = AuthenticationHandler.TokenValidationParameters;
});
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder(
JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build();
options.AddPolicy(nameof(ExistingUserRequirement),
policy => policy.Requirements.Add(new ExistingUserRequirement()));
});
services.AddTransient<IAuthorizationHandler, ExistingUserHandler>();
There i query the DataContext if the user is existing and active.
What works:
If I configure the Authorization attribute on an action everything works fine:
[HttpPost]
[Authorize(Policy = nameof(ExistingUserRequirement))]
public JsonResult Post([FromBody]CreateStoryViewModel viewModel) { ...}
I can access the requests user identity using HttpContextAccessor.HttpContext.User.Identity.Name.
What not works: If I configure the attribute on my BaseController the Identity-context seems the be missing when the ExistingUserHandler fires up:
[Authorize(Policy = nameof(ExistingUserRequirement))]
public abstract class BaseController : Controller { ... }
Now Identity.Name returns always NULL:
public class ExistingUserHandler : AuthorizationHandler<ExistingUserRequirement>
{
private IHttpContextAccessor HttpContextAccessor { get; }
private SaycleContext SaycleContext { get; }
public ExistingUserHandler(IHttpContextAccessor httpContextAccessor, SaycleContext saycleContext)
{
HttpContextAccessor = httpContextAccessor;
SaycleContext = saycleContext;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext authorizationContext, ExistingUserRequirement requirement)
{
var exists = false;
if (Guid.TryParse(HttpContextAccessor.HttpContext.User.Identity.Name, out var currentUserId))
{
exists = SaycleContext.Users.Any(u => Equals(u.Id, currentUserId));
}
if (!exists)
{
throw new NonExistingUserException();
}
authorizationContext.Succeed(requirement);
return Task.CompletedTask;
}
}
Am I missing anything? Why can the identity-context not be resolved using the Authorize attribute on my parent BaseController?

Categories