ASP. Net core2.2 multi user authentication and authorization

Time:2019-10-20

Preface

ASP. Net core2.2 user authentication and authorization is a very detailed and thoughtful introduction. I am interested in these two articles:

  • Cookie authentication
  • Role based authorization

My project has two types of users:

  • Wechat public account user, whose user name is openid of public account
  • The user name of enterprise wechat is the user ID of enterprise wechat.

Some people in each type of user have the “admin” role

Because users of enterprise wechat may be users of wechat public account at the same time, i.e. one person and two names, multi-user authentication and authorization are required. Let’s use the code to talk the most succinctly, as follows:

public class DemoController : Controller
{
 /// <summary>
 ///Module used by enterprise wechat users
 /// </summary>
 /// <returns></returns>
 public IActionResult Work()
 {
 return Content(User.Identity.Name +User.IsInRole("Admin"));
 }
 /// <summary>
 ///Module used by enterprise wechat administrator
 /// </summary>
 /// <returns></returns>
 public IActionResult WorkAdmin()
 {
 return Content(User.Identity.Name + User.IsInRole("Admin"));
 }
 /// <summary>
 ///Module used by wechat public account users
 /// </summary>
 /// <returns></returns>
 public IActionResult Mp()
 {
 return Content(User.Identity.Name + User.IsInRole("Admin"));
 }
 /// <summary>
 ///Module used by wechat public account administrator
 /// </summary>
 /// <returns></returns>
 public IActionResult MpAdmin()
 {
 return Content(User.Identity.Name + User.IsInRole("Admin"));
 }
}

Let’s do it step by step.

The first step is to transform startup

Modify the configureservices method and add the following code

services.AddAuthentication
   (
   "Work" // is to set a default cookie verification name. By default, it means that you can not write when you need to. In addition, cookieauthenticationdefaults.authenticationscheme is often used, which is the string constant "cookies".
   )
   .AddCookie
   (
   "Work", // cookie validation name, "work" can be omitted because it is the default name
   option =>
   {
    Option. Loginpath = new pathstring ("/ demo / worklogin"); // set the path for validation
    Option. Accessdenied path = new pathstring ("/ demo / workdenied"); // set the path of unauthorized access jump
   }).AddCookie("Mp", option =>
   {
    option.LoginPath = new PathString("/Demo/MpLogin");
    option.AccessDeniedPath = new PathString("/Demo/MpDenied");
   });

Modify the configure method and add the following code


app.UseAuthentication();

Step 2 add verification

public async Task WorkLogin(string returnUrl)
 {
  var claims = new List<Claim>
  {
   new Claim(ClaimTypes.Name, "UserId"),
   New claim (claimtypes. Role, "admin") // if administrator
  };

  Var claimsidentity = new claimsidentity (claims, "work"); // "," work "can be omitted because it is the default name

  var authProperties = new AuthenticationProperties
  {
   AllowRefresh = true,
   //ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10), 
   // The time at which the authentication ticket expires. A 
   // value set here overrides the ExpireTimeSpan option of 
   // CookieAuthenticationOptions set with AddCookie.
   IsPersistent = false, // persistent saving. I don't know exactly what it means. I'd like to explain if anyone knows.
   //IssuedUtc = <DateTimeOffset>,
   // The time at which the authentication ticket was issued.
   RedirectUri = returnUrl ?? "/Demo/Work"
  };

  await HttpContext.SignInAsync("Work", new ClaimsPrincipal(claimsIdentity), authProperties);
 }
 public IActionResult WorkDenied()
 {
  return Forbid();
 }


 public async Task MpLogin(string returnUrl)
 {
  var claims = new List<Claim>
  {
   new Claim(ClaimTypes.Name, "OpenId"),
   New claim (claimtypes. Role, "admin") // if administrator
  };

  Var claimsid = new claimsid (claims, "MP"); // "," MP "cannot be omitted because it is not the default name

  var authProperties = new AuthenticationProperties
  {
   AllowRefresh = true,
   IsPersistent = false,
   RedirectUri = returnUrl ?? "/Demo/Mp"
  };

  await HttpContext.SignInAsync("Mp", new ClaimsPrincipal(claimsIdentity), authProperties);
 }
 public IActionResult MpDenied()
 {
  return Forbid();
 }

Step 3 add authorization

Add [authorize] before the corresponding action.

/// <summary>
 ///Module used by enterprise wechat users
 /// </summary>
 /// <returns></returns>
 [Authorize(
  Authenticationschemes = "work" // the default name can be omitted
  )]
 public IActionResult Work()
 {
  return Content(User.Identity.Name + User.IsInRole("Admin"));
 }
 /// <summary>
 ///Module used by enterprise wechat administrator
 /// </summary>
 /// <returns></returns>
 [Authorize(AuthenticationSchemes ="Work",Roles ="Admin")]
 public IActionResult WorkAdmin()
 {
  return Content(User.Identity.Name + User.IsInRole("Admin"));
 }
 /// <summary>
 ///Module used by wechat public account users
 /// </summary>
 /// <returns></returns>
 [Authorize(AuthenticationSchemes ="Mp")]
 public IActionResult Mp()
 {
  return Content(User.Identity.Name + User.IsInRole("Admin"));
 }
 /// <summary>
 ///Module used by wechat public account administrator
 /// </summary>
 /// <returns></returns>
 [Authorize(AuthenticationSchemes ="Mp",Roles ="Admin")]
 public IActionResult MpAdmin()
 {
  return Content(User.Identity.Name + User.IsInRole("Admin"));
 }

Run Ctrl + F5. The screenshot is as follows:

Finally, talk about the pit and help

pit

The initial verification code is as follows:

public async Task<IActionResult> Login(string returnUrl)
 {
  var claims = new List<Claim>
  {
   new Claim(ClaimTypes.Name, "UserId"),
   New claim (claimtypes. Role, "admin") // if administrator
  };

  Var claimsidentity = new claimsidentity (claims, "work"); // "," work "can be omitted because it is the default name

  var authProperties = new AuthenticationProperties
  {
   //AllowRefresh = true,
   //IsPersistent = false,
   //RedirectUri 
  };

  await HttpContext.SignInAsync("Work", new ClaimsPrincipal(claimsIdentity), authProperties);

  return Content("OK");
 }
  • The return type is task < iactionresult >, because I don’t want to write view, so I wrote the sentence return content (“OK”);
  • Code copied from website, no content set for authenticationproperties

After running, it calls login continuously, baidu changes various codes for a long time, and finallyreturn Content("OK");Change toreturn RedirectToAction("Index");All OK!

Guess whyreturn Content("OK");Automatically call the redirecturi of authenticationproperties, and automatically call itself when the redirecturi is empty. I don’t know.

At this time, we should pay attention to the redirecturi and return to the returnurl. Can we automatically jump by assigning a returnurl to the redirecturi?

Exactly,return Content("OK");It’s time to jump.return RedirectToAction("Index");Invalid.

Finally putTask<IActionResult>Change to task, delete return… And everything is perfect! (weak ask, is that how it should be written? I’ve been taking a detour?)

Seek help

User has attribute identities. It seems that there can be multiple identities. How can there be?

summary

The above is the whole content of this article. I hope that the content of this article has a certain reference learning value for everyone’s study or work. If you have any questions, you can leave a message and exchange. Thank you for your support for developepaar.