使用ASP.Net Core 3.1
我是身份验证和授权的新手。对于我们的REST API,我已经使用auth0 idp实现了身份验证(这很简单,因为它们提供了文档!)
现在我的老板希望在应用程序内处理授权。我不确定该如何实施。
如果任何人都可以提出有关实现方法的方向或路径,那将是非常有帮助的。
答案 0 :(得分:0)
我更喜欢的最佳方式是依靠可信赖的 Microsoft Identity 进行身份验证和授权。我们在 2013 年使用 .net MVC 4 做到了,现在又在 2021 年使用 .Net Core 5。 对于 .Net Core 5.0,请按照以下步骤操作:
1. Nuget - Search for - aspnetcore.identity
2. Install Microsoft.AspNetCore.Identity.EntityFrameworkCore
In the models folder create a class **User.cs** as below:
> using Microsoft.AspNetCore.Identity;
public class User:IdentityUser
{
}
3. Modify your already installed EF DbContext class
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
public class EventContext: IdentityDbContext<User>
{
....
}
5. Open Package Manager Console and type
**Add-Migration AddIdentityTables**
**Update-database**
You should see user management tables generated in your database now!
6. Configure middleware for identity
**In Startup.cs**
**at ConfigureServices()**
services.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<EventContext>()
.AddDefaultTokenProviders();
**at Configure()**
app.UseAuthorization();
app.UseAuthentication();
Add Login Lout to nav bar
- Open Views/Share/_Layout page.
- Add only the highlighted code after the Admin link as shown in the next page:
@using Microsoft.AspNetCore.Identity
@inject SignInManager<User> signInManager
<ul class="navbar-nav">
@if (signInManager.IsSignedIn(User))
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Manage" asp-action="Index" title="Manage">Hello @User.Identity.Name!</a>
</li>
<li class="nav-item">
<form class="form-inline" asp-area="" asp-controller="Account" asp-action="Logout" method="post">
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp- action="Register">Register </a>
</li>
<li>
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Login">Log in</a>
</li>
}
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Admin" asp-action="List">Admin</a>
</li>
</div>
</div>
</nav>
Create Account Controller:
using Microsoft.AspNetCore.Identity;
public class AccountController : Controller
{
private UserManager<User> userManager;
private SignInManager<User> signInManager;
public AccountController(UserManager<User> userMngr,
SignInManager<User> signInMngr)
{
userManager = userMngr;
signInManager = signInMngr;
}
}
Add the view model
- Add class RegisterViewModel class in Models
[Required(ErrorMessage = "Please enter a username.")]
[StringLength(100)]
public string Username { get; set; }
[Required(ErrorMessage = "Please enter a password.")]
[DataType(DataType.Password)]
[Compare("ConfirmPassword")]
public string Password { get; set; }
[Required(ErrorMessage = "Please confirm your password.")]
[DataType(DataType.Password)]
[Display(Name = "Confirm Password")]
public string ConfirmPassword { get; set; }
Add the view for registration
In the Views Folder create a new folder named Account to place the views for the AccountController. In this folder add a new view named Register.
@model RegisterViewModel
@{
ViewBag.Title = "Register";
}
<h2>Register</h2>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<form method="post" asp-action="Register">
<div class="form-group row">
<div class="col-sm-2"><label>Username:</label></div>
<div class="col-sm-4">
<input type="text" asp-for="Username"
class="form-control" />
</div>
<div class="col">
<span asp-validation-for="Username"
class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-sm-2"><label>Password:</label></div>
<div class="col-sm-4">
<input type="password" asp-for="Password"
class="form-control" />
</div>
<div class="col">
<span asp-validation-for="Password"
class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-sm-2"><label>Confirm Password:</label></div>
<div class="col-sm-4">
<input type="password" asp-for="ConfirmPassword"
class="form-control" />
</div>
</div>
<div class="row">
<div class="offset-2 col-sm-4">
<button type="submit" class="btn btn-primary">Register</button>
</div>
</div>
<div class="row">
<div class="offset-2 col-sm-4">
Already registered? <a asp-action="LogIn">Log In</a>
</div>
</div>
</form>
**Add action method for registration .**
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new User { UserName = model.Username };
var result = await userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
bool isPersistent = false;
await signInManager.SignInAsync(user, isPersistent);
return RedirectToAction("Index", "Home");
}
else
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
}
return View(model);
}
**Add the view model**
- Add class LoginViewModel class in Models
[Required(ErrorMessage = "Please enter a username.")]
[StringLength(100)]
public string Username { get; set; }
[Required(ErrorMessage = "Please enter a password.")]
[StringLength(100)]
public string Password { get; set; }
public string ReturnUrl { get; set; }
public bool RememberMe { get; set; }
Add the view for login
In the Views/Account folder add a view named Login.
@model LoginViewModel
@{
ViewBag.Title = "Login";
}
<h2>Login</h2>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<form method="post" asp-action="LogIn" asp-route-returnUrl="@Model.ReturnUrl">
<div class="form-group row">
<div class="col-sm-2"><label>Username:</label></div>
<div class="col-sm-4">
<input type="text" asp-for="Username"
class="form-control" />
</div>
<div class="col">
<span asp-validation-for="Username"
class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-sm-2"><label>Password:</label></div>
<div class="col-sm-4">
<input type="password" asp-for="Password"
class="form-control" />
</div>
<div class="col">
<span asp-validation-for="Password"
class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="offset-sm-2 col-sm-4">
<input type="checkbox" title="Remember Me" asp-for="RememberMe"
class="form-check-inline" />
<label asp-for="RememberMe">Remember Me</label>
</div>
</div>
<div class="row">
<div class="offset-2 col-sm-4">
<button type="submit" class="btn btn-primary">Log In</button>
</div>
</div>
<div class="row">
<div class="offset-2 col-sm-4">
Not registered? <a asp-action="Register">Register as a new user</a>
</div>
</div>
</form>
**Add action methods for login**
[HttpGet]
public IActionResult LogIn(string returnURL = "")
{
var model = new LoginViewModel { ReturnUrl = returnURL };
return View(model);
}
[HttpPost]
public async Task<IActionResult> LogIn(LoginViewModel model)
{
if (ModelState.IsValid)
{
var result = await signInManager.PasswordSignInAsync(
model.Username, model.Password, isPersistent: model.RememberMe,
lockoutOnFailure: false);
if (result.Succeeded)
{
if (!string.IsNullOrEmpty(model.ReturnUrl) &&
Url.IsLocalUrl(model.ReturnUrl))
{
return Redirect(model.ReturnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
}
ModelState.AddModelError("", "Invalid username/password.");
return View(model);
}
**Finally, handle logout in authentication:**
[HttpPost]
public async Task<IActionResult> LogOut()
{
await signInManager.SignOutAsync();
return RedirectToAction("Index", "Home");
}
**Access Restriction by Authorization**
using Microsoft.AspNetCore.Authorization;
[Authorize]
public class AdminController : Controller
{
………….
}