IHttpContextAccessor returns null Username claims in AspNetCore 5 API Controller - asp.net-core

I have some Api Controllers in my AspNetCore 5 web application containing some methods which are available to unauthenticated users and some of them are only available for authorized users.
Assume that there is a ReviewController which all users can add review, but if the user is authenticated, we should fill username field.
Let's say in TestController:
[Route("api/[controller]/[action]/")]
[ApiController]
public class TestController
{
private readonly IHttpContextAccessor _httpContextAccessor;
public TestController(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
[HttpGet]
public string TestA()
{
return _httpContextAccessor.HttpContext.User.Identity.Name;
}
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public string TestB()
{
return _httpContextAccessor.HttpContext.User.Identity.Name;
}
}
The only difference between two methods is Authorize attribute.
I setup JwtBearer authentication in the application with below setup.
ConfigureServices:
public override void ConfigureServices(IServiceCollection services)
{
var jwtConfig = new JwtConfig
{
Secret = "some secrets!",
Audience = "http://localhost:5000",
Expires = 600,
Issuer = "http://localhost:5000"
};
services.AddAuthorization();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwt =>
{
var key = Encoding.ASCII.GetBytes(jwtConfig.Secret);
jwt.SaveToken = true;
jwt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = true,
ValidateAudience = true,
RequireExpirationTime = true,
ValidateLifetime = true,
SaveSigninToken = true,
ValidAudience = jwtConfig.Audience,
ValidIssuer = jwtConfig.Issuer
};
});
services.AddHttpContextAccessor();
services.AddMvcCore()
.AddDataAnnotations()
.AddApiExplorer()
.AddFormatterMappings()
.AddCors();
}
And Configure:
public void Configure(IApplicationBuilder app)
{
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
When I am calling TestB it returns the logged in username. But, when I am calling TestA it returns null.
Why IHttpContextAccessor's user claims are not loaded and how can I access to IHttpContextAccessor's username and user claims in any condition? Assume that I am using that in other layers than controllers.

Related

.Net Core microservice and inspecting Cognito JWT claims for use in authorization

I am developing a .net service that I am passing a Cognito generated JWT in the client that has a group claim that I hope to use to restrict API access as the JWT is passed in as a Bearer token with each API call from the front-end. e.g.
"cognito:groups":["Guest"]
In my code now I have added:
services.AddAuthentication(DefaultScheme = JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
RoleClaimType = "cognito:groups"
};
});
I have setup up my roles and my permissions using the HeimGuard project. In testing as I change roles in the Bearer token none of my APIs that restrict access to Guest do not deny access when decorated with [Authorize]. So, nothing is restricted. Any thoughts or ideas you have in how to solve this problem helps immensly. Thank you!!
I tried custom AuthorizeAttribute as below:
To create the Token:
public class UserModel
{
public string Username { get; set; }
public string Role { get; set; }
public string EmailAddress { get; set; }
public string PassWord { get; set; }
public string Right { get; set; }
}
[HttpPost]
public IActionResult Authenticate(UserModel someuser)
{
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.Role, someuser.Role),
new Claim(ClaimTypes.Name, someuser.Username),
new Claim("Right", someuser.Right)
};
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
_config["Jwt:Issuer"],
_config["Jwt:Issuer"],
signingCredentials: credentials,
expires: DateTime.Now.AddMinutes(2),
claims: claims
);
string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
return Content(jwtToken);
}
codes in appsettings.json:
"Jwt": {
"Key": "ThisismySecretKey",
"Issuer": "Test.com"
}
Custom requirement:
public class WriteRequirement : AuthorizationHandler<WriteRequirement>, IAuthorizationRequirement
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, WriteRequirement requirement)
{
var right = context.User.FindFirst("Right").Value;
if(right=="Write")
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
return Task.CompletedTask;
}
}
in startup class:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = false,
ValidateIssuerSigningKey = false,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});
services.AddSingleton<IAuthorizationHandler, WriteRequirement>();
services.AddAuthorization(opyions => { opyions.AddPolicy("Write", policy => policy.Requirements.Add(new WriteRequirement())); });
...
}
The Action need Authrization:
[HttpGet]
[Authorize(Roles ="Admin")]
[Authorize(Policy="Write")]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2", "value3", "value4", "value5" };
}
The Result:

How to get the id of the user out of jwt token in .net core or how to return a value from a custom authorization attribute?

I create my token in the following way
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user.Id.ToString()),
new Claim(ClaimTypes.Role, "tada")
}),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var encryptedtoken = tokenHandler.WriteToken(token);
And now i would like to simply get the users id from my authorize attribute and put it in the context somehow?
I know i can decode the token like so
[Authorize(Roles = "tada")]
public IActionResult Get()
{
var token = HttpContext.Request.Headers[HeaderNames.Authorization][0];
var tokenArray = token.Split(" ");
var handler = new JwtSecurityTokenHandler();
var tokenS = handler.ReadToken(tokenArray[1]) as JwtSecurityToken;
return Ok(tokenS.Payload.SingleOrDefault(t => t.Key == "unique_name").Value);
}
But how do i reuse this code in a more clever way can i create my own authorization attribute that will store it in the context if there is no way, how do i create a singleton/scoped/transient service?
here's how i configure jwt
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.AddDbContext<CatstagramDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddIdentity<User, IdentityRole>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequiredLength = 6;
})
.AddEntityFrameworkStores<CatstagramDbContext>();
var applicationSettingConfiguration = Configuration.GetSection("ApplicationSettings");
services.Configure<AppSettings>(applicationSettingConfiguration);
var appSettings = applicationSettingConfiguration.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddControllers();
}
// 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();
app.UseMigrationsEndPoint();
}
app.UseCors(options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.ApplyMigrations();
}
}
I am using this function to get any token claim value
public static string GetClaimValue(HttpContext httpContext, string valueType)
{
if (string.IsNullOrEmpty(valueType)) return null;
var identity = httpContext.User.Identity as ClaimsIdentity;
var valueObj = identity == null ? null : identity.Claims.FirstOrDefault(x => x.Type == valueType);
return valueObj==null? null:valueObj.Value;
}
you can use it like this
var name = GetClaimValue(HttpContext, "unique_name");
When the authentication middleware authenticates the request, it populates HttpContext.User property with a ClaimsPrincipal that holds the claims for the current user.
ClaimsPrincipal class has an extension method in System.Security.Claims in namespace called FindFirstValue.
User.FindFirstValue("unique_name");
gives you the value for the first unique_name claim.
Source: https://github.com/dotnet/aspnetcore/blob/2be49d930a5fb53e781abd175c3b2a8f8b7827d4/src/Identity/Extensions.Core/src/PrincipalExtensions.cs

Error trying to get authenticate with google in ASP.NET Core 3.1 No authentication handler is registered

The Error
This is my startup class
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Demand authentication in the whole application
services.AddControllersWithViews(o => o.Filters.Add(new AuthorizeFilter()));
services.AddScoped<IConferenceRepository, ConferenceRepository>();
services.AddScoped<IProposalRepository, ProposalRepository>();
services.AddScoped<IAttendeeRepository, AttendeeRepository>();
services.AddScoped<IUserRepository, UserRepository>();
services.AddDbContext<ConfArchDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
assembly =>
assembly.MigrationsAssembly(typeof(ConfArchDbContext).Assembly.FullName)));
services
.AddAuthentication(options =>
{
options.DefaultScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme =
GoogleDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.Cookie.IsEssential = true;
//options.Cookie.SameSite = SameSiteMode.None;
})
.AddGoogle(options =>
{
options.SignInScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.ClientId =
Configuration["Authentication:Google:ClientId"];
options.ClientSecret =
Configuration["Authentication:Google:ClientSecret"];
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
//app.UseIdentity();
// app.UseAuthentication();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Conference}/{action=Index}/{id?}");
});
}
}
this is my controller, the error is thrown in the line: var result = await HttpContext.AuthenticateAsync(
public class AccountController : Controller
{
private readonly IUserRepository userRepository;
public AccountController(IUserRepository userRepository)
{
this.userRepository = userRepository;
}
// This method must be anonymous to allow access to not logged users
[AllowAnonymous]
public IActionResult Login(string returnUrl = "/")
{
return View(new LoginModel { ReturnUrl = returnUrl });
}
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login(LoginModel model)
{
// Looking for user in local repository in the class userrepository
var user = userRepository.GetByUsernameAndPassword(model.Username, model.Password);
if (user == null)
return Unauthorized();
// Data of the user, claims class is used to represent the data user
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.Name),
new Claim(ClaimTypes.Role, user.Role),
new Claim("FavoriteColor", user.FavoriteColor)
};
// Object to save in Identity object type ClaimsIdentity
var identity = new ClaimsIdentity(claims,
CookieAuthenticationDefaults.AuthenticationScheme);
// Create claims principal object with the Identity
var principal = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
principal,
new AuthenticationProperties { IsPersistent =
model.RememberLogin,
ExpiresUtc= DateTime.UtcNow.AddMinutes(10)
});
return LocalRedirect(model.ReturnUrl);
}
[AllowAnonymous]
public IActionResult LoginWithGoogle(string returnUrl = "/")
{
var props = new AuthenticationProperties
{
RedirectUri = Url.Action("GoogleLoginCallback"),
Items =
{
{ "returnUrl", returnUrl }
}
};
return Challenge(props, GoogleDefaults.AuthenticationScheme);
}
[AllowAnonymous]
public async Task<IActionResult> GoogleLoginCallback()
{
// read google identity from the temporary cookie
var result = await HttpContext.AuthenticateAsync(
ExternalAuthenticationDefaults.AuthenticationScheme);
var externalClaims = result.Principal.Claims.ToList();
var subjectIdClaim = externalClaims.FirstOrDefault(
x => x.Type == ClaimTypes.NameIdentifier);
var subjectValue = subjectIdClaim.Value;
var user = userRepository.GetByGoogleId(subjectValue);
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.Name),
new Claim(ClaimTypes.Role, user.Role),
new Claim("FavoriteColor", user.FavoriteColor)
};
var identity = new ClaimsIdentity(claims,
CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
// delete temporary cookie used during google authentication
await HttpContext.SignOutAsync(
ExternalAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme, principal);
return LocalRedirect(result.Properties.Items["returnUrl"]);
}
// Action to logout
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Redirect("/");
}
}
I figure out the answer, the in the configure services code should be so:
// Demand authentication in the whole application
services.AddControllersWithViews(o => o.Filters.Add(new
AuthorizeFilter()));
services.AddScoped<IConferenceRepository, ConferenceRepository>();
services.AddScoped<IProposalRepository, ProposalRepository>();
services.AddScoped<IAttendeeRepository, AttendeeRepository>();
services.AddScoped<IUserRepository, UserRepository>();
services.AddDbContext<ConfArchDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
assembly =>
assembly.MigrationsAssembly(typeof(ConfArchDbContext).Assembly.FullName)));
services.AddAuthentication(o => {
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
//o.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddCookie()
.AddCookie(ExternalAuthenticationDefaults.AuthenticationScheme)
.AddGoogle(o =>
{ // ClienteId and Secret to authenticate the user from Google
o.SignInScheme =
ExternalAuthenticationDefaults.AuthenticationScheme;
o.ClientId = Configuration["Authentication:Google:ClientId"];
o.ClientSecret =
Configuration["Authentication:Google:ClientSecret"];
});

How to Authorize Controller .NET Core API

I'm able to generate tokens succesfully when user login the app.But after I added [Authorize] on my controller,that token comes from header cannot pass the authorization.On Postman returns Unauthorized even though sending up-to date token in header to controller.Before added [Authorize] that worked very well
Startup.cs
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.AddDbContext<DataContext>(x => x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllers().AddNewtonsoftJson(opt => {
opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.AddCors();
services.AddAutoMapper(typeof(AppointmentRepository).Assembly);
services.AddScoped<IHospitalRepository, HospitalRepository>();
services.AddScoped<IAppointmentRepository, AppointmentRepository>();
services.AddScoped<IPatientRepository, PatientRepository>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddControllers();
}
// 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();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseCors(x => x.WithOrigins().AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
login Method in controller
[HttpPost("login")]
public async Task<IActionResult> Login(PatientLoginDto patientLoginDto)
{
//if user exists or not
var patientFromRepo = await _repo.Login(patientLoginDto.IdentityNumber, patientLoginDto.Password);
if (patientFromRepo == null)
{ return Unauthorized(); }
var claims = new[]
{
//Token has two claim username and id
new Claim(ClaimTypes.NameIdentifier,patientFromRepo.Id.ToString()),
new Claim(ClaimTypes.NameIdentifier,patientFromRepo.Name)
};
//key generated
var key = new SymmetricSecurityKey(Encoding.UTF8
.GetBytes(_config.GetSection("AppSettings:Token").Value));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
var tokenDescriptor = new SecurityTokenDescriptor
{
//passing claims
Subject = new ClaimsIdentity(claims),
//expiry date in hours
Expires = DateTime.Now.AddDays(1),
SigningCredentials = creds
};
var tokenHandler = new JwtSecurityTokenHandler();
//storing token here(based on token descriptor object)
var token = tokenHandler.CreateToken(tokenDescriptor);
var patient = _mapper.Map<PatientLoggedinDto>(patientFromRepo);
return Ok(new
{
//as response send back to the client
token = tokenHandler.WriteToken(token),
patient
});
}
}
You need register the AuthenticationMiddleware before app.UseAuthorization();:
app.UseRouting();
app.UseAuthentication(); // add this line. NOTE The order is important.
app.UseAuthorization();
// ... other middlewares

blazor webassembly System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request)

I have a blazor project that is dotnet core hosted. I am working on blazor authentication following this tutorial. Everything is ok on the server side because I was able to use Postman to create users successfully. I have tried different suggestions online but non work for me. Some suggested CORS which I fixed, some route which I amended but problem still persist.
I have been having issue debugging as I cant get break point in the browser console. I have debugged some blazor project I could set break points and view local variables but I couldnt with the current project. I dont know if its a bug.
server startup.cs
namespace EssentialShopCoreBlazor.Server
{
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration _configuration)
{
Configuration = _configuration;
}
readonly string AllowSpecificOrigins = "allowSpecificOrigins";
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<IdentityUsersModel, IdentityRole>()
.AddEntityFrameworkStores<DbContext>()
.AddDefaultTokenProviders();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtAudience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSecurityKey"]))
};
});
services.AddCors(options =>
{
options.AddPolicy(AllowSpecificOrigins,
builder =>
{
builder.WithOrigins("https://localhost:44365", "https://localhost:44398")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
services.AddScoped<AccountAuthController>();
services.AddMvc().AddNewtonsoftJson();
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCompression();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBlazorDebugging();
}
app.UseCors(AllowSpecificOrigins);
app.UseStaticFiles();
app.UseClientSideBlazorFiles<Client.Startup>();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
});
}
}
}
controller
namespace EssentialShopCoreBlazor.Server.Controllers
{
[Route("essential/users/")]
public class AccountAuthController : ControllerBase
{
private static UserModel LoggedOutUser = new UserModel { IsAuthenticated = false };
private readonly UserManager<IdentityUsersModel> userManager;
private readonly IConfiguration configuration;
private readonly SignInManager<IdentityUsersModel> signInManager;
public AccountAuthController(UserManager<IdentityUsersModel> _userManager, SignInManager<IdentityUsersModel> _signInManager, IConfiguration _configuration)
{
userManager = _userManager;
signInManager = _signInManager;
configuration = _configuration;
}
[HttpPost]
[Route("create")]
public async Task<ActionResult<ApplicationUserModel>> CreateUser([FromBody] ApplicationUserModel model)
{
var NewUser = new IdentityUsersModel
{
UserName = model.UserName,
BusinessName = model.BusinessName,
Email = model.Email,
PhoneNumber = model.PhoneNumber
};
var result = await userManager.CreateAsync(NewUser, model.Password);
if (!result.Succeeded)
{
var errors = result.Errors.Select(x => x.Description);
return BadRequest(new RegistrationResult { Successful = false, Errors = errors });
}
return Ok(new RegistrationResult { Successful = true });
}
}}
client service
public class AuthService : IAuthService
{
private readonly HttpClient _httpClient;
private readonly AuthenticationStateProvider _authenticationStateProvider;
private readonly ILocalStorageService _localStorage;
string BaseUrl = "https://localhost:44398/essential/users/";
public AuthService(HttpClient httpClient,
AuthenticationStateProvider authenticationStateProvider,
ILocalStorageService localStorage)
{
_httpClient = httpClient;
_authenticationStateProvider = authenticationStateProvider;
_localStorage = localStorage;
}
public async Task<RegistrationResult> Register(ApplicationUserModel registerModel)
{
var result = await _httpClient.PostJsonAsync<RegistrationResult>(BaseUrl + "create", registerModel);
return result;
}
}