0

Working with ASP.Net Core 3.1

I am new to authentication and authorization. For our REST API, I have implemented authentication with auth0 idp (which is fairly simple, since they provide documentation!)

Now my boss wants authorization to be handled within the application. I am not sure how to implement that one.

If anyone can suggest a direction or path on how to implement that, it would be immensely helpful.

2
  • 1
    First off, do you appreciate the difference between the two? This question is likely to be off topic for SO because "design my X for me" is answered with an opinion, you need to do the design, hit the stumbling blocks when doing the implementation and ask us for help with that part, rather than the design. As a pointer, and the way we do it is that the identity provider returns some variable number of claims, which identify properties of the user or their context. We then use these claims to work out eg if the user calling method X of controller Y has permission to eg delete the appointment Commented Sep 21, 2020 at 5:50
  • 1
    The identity provider can alter the claims it sends, probably by some UI on auth0, so when someone is upgraded from "Worker" to "Supervisor" they can delete appointments. See learn.microsoft.com/en-us/aspnet/core/security/authorization/… for example Commented Sep 21, 2020 at 5:53

1 Answer 1

1

The best way I prefer is to rely on trustable Microsoft Identity for authentication and authorization. We did it in 2013 using .net MVC 4 and now again in 2021 to .Net Core 5. For .Net Core 5.0 please follow below steps:

 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 { …………. }
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.