For a simple log reading application, I need to allow a form authentication based on user/password match. The check is done against data stored inside the app settings file so I don't have a DB connected that stores the user data.
Googling around I've seen I should inject the private readonly SignInManager<IdentityUser> _signInManager;
then use the ``` await _signInManager.SignInAsync(new IdentityUser { UserName = "xxx" }, false);````
But I'm not able to configure the service's dependencies...
did anyone get an example?
Thanks
#update #1
public class LoginViewModel
{
#region Properties
/// <summary>
/// Gets or sets to username address.
/// </summary>
[Required]
[Display(Name = "Username")]
public string Username { get; set; }
/// <summary>
/// Gets or sets to password address.
/// </summary>
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
#endregion
}
CodePudding user response:
As far as I know you should use SignInManager
when using ASP.NET Core Identity.
In your case a authentication based on Claims would be much easier. This can be achived like this:
public async Task<IActionResult> OnPostAsync(string? returnUrl = null)
{
if (ModelState.IsValid)
{
// Validate your username and password here
var claims = new List<Claim>
{
/* Set your claims here */
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
IsPersistent = Input.RememberMe,
RedirectUri = returnUrl
};
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
return LocalRedirect(returnUrl);
}
return Page();
}
Within your startup process you'll need to configure it to use cookie based authentication.
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>{});
builder.Services.AddAuthorization(options =>{});
CodePudding user response:
allow a form authentication based on user/password match. The check is done against data stored inside the app settings file
Below is a work demo, you can refer to it.
UserModel :
public class UserModel { public string Username { get; set; } public string Password { get; set; } }
LoginModel:
public class LoginModel
{
[Required]
[Display(Name ="Username")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
public bool RememberLogin { get; set; }
public string ReturnUrl { get; set; }
}
2.data in appsettings:
"UserModels": [
{
"UserName": "aa",
"Password": "123"
},
{
"UserName": "bb",
"Password": "123"
}
]
3.AccountController:
public class AccountController : Controller
{
//Sample Users Data, it can be fetched with the use of any ORM
public List<UserModel> users = null;
private readonly IConfiguration _config;
public AccountController(IConfiguration config)
{
_config = config;
users = _config.GetSection("UserModels").Get<List<UserModel>>();
}
public IActionResult Login(string ReturnUrl = "/")
{
LoginModel objLoginModel = new LoginModel();
objLoginModel.ReturnUrl = ReturnUrl;
return View(objLoginModel);
}
[HttpPost]
public async Task<IActionResult> Login(LoginModel objLoginModel)
{
if (ModelState.IsValid)
{
var user = users.Where(x => x.Username == objLoginModel.UserName && x.Password == objLoginModel.Password).FirstOrDefault();
if (user == null)
{
//Add logic here to display some message to user
ViewBag.Message = "Invalid Credential";
return View(objLoginModel);
}
else
{
//A claim is a statement about a subject by an issuer and
//represent attributes of the subject that are useful in the context of authentication and authorization operations.
var claims = new List<Claim>() {
new Claim(ClaimTypes.Name,user.Username)
};
//Initialize a new instance of the ClaimsIdentity with the claims and authentication scheme
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
//Initialize a new instance of the ClaimsPrincipal with ClaimsIdentity
var principal = new ClaimsPrincipal(identity);
//SignInAsync is a Extension method for Sign in a principal for the specified scheme.
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
principal, new AuthenticationProperties() { IsPersistent = objLoginModel.RememberLogin });
return LocalRedirect(objLoginModel.ReturnUrl);
}
}
return View(objLoginModel);
}
public async Task<IActionResult> LogOut() {
//SignOutAsync is Extension method for SignOut
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
//Redirect to home page
return LocalRedirect("/");
}
}
4.In Program.cs, add below code:
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(x=>x.LoginPath="/account/login");
...
app.UseAuthentication();
app.UseAuthorization();
5.Login view:
@model LoginModel
@{
ViewData["Title"] = "Login";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Login</h2>
<hr />
<div >
<div >
<form asp-action="Login">
<div asp-validation-summary="ModelOnly" ></div>
@if (!string.IsNullOrEmpty(ViewBag.Message))
{
<span >
@ViewBag.Message
</span>
}
@Html.HiddenFor(x => x.ReturnUrl)
<div >
<label asp-for="UserName" ></label>
<input asp-for="UserName" />
<span asp-validation-for="UserName" ></span>
</div>
<div >
<label asp-for="Password" ></label>
<input asp-for="Password" />
<span asp-validation-for="Password" ></span>
</div>
<div >
<div >
<label>
<input asp-for="RememberLogin" /> @Html.DisplayNameFor(model => model.RememberLogin)
</label>
</div>
</div>
<div >
<input type="submit" value="Login" />
</div>
</form>
</div>
</div>