简体   繁体   中英

Authentication of a user in ASP.NET Core 5 Web API

In a Web API project I am using the following method to sign in my user but at a latter point I want to get my user first name and last name. I am using Web API and .NET 5.

public AuthenticateResponse Authenticate(AuthenticateRequest model, string ipAddress)
{
    var user = _userManager.Users
                           .Where(w => w.UserName == model.Username)
                           .FirstOrDefault();

    // This doesn't count login failures towards account lockout
    // To enable password failures to trigger account lockout, set 
    lockoutOnFailure: true

    var result = _signInManager.PasswordSignInAsync(model.Username, model.Password, true, lockoutOnFailure: false);

    User users = new User();
    users.Username = model.Username;
    users.Password = model.Password;
    users.FirstName = user.FirstName;
    users.LastName = user.LastName;

    if (result.Result.Succeeded)
    {
        // return null if user not found
        if (user == null)
            return null;
    }

    // authentication successful so generate jwt and refresh tokens
    var jwtToken = generateJwtToken(users);
    var refreshToken = generateRefreshToken(ipAddress);

    // save refresh token
    // users.RefreshTokens.Add(refreshToken);

    return new AuthenticateResponse(users, jwtToken, null);
 }

I have this method in a UserService class how would one best access the values from

users.FirstName
users.LastName

from the Web API controller which could be say clubs. As you see I am using the signin manager and usermanager should I simply load an instance of that in my ClubController .

My API method is

[HttpPost]
[Route("Clubs/Create")]
public async Task<IActionResult> Create(ClubViewModelApi clubModel)
{
    if (ModelState.IsValid)
    {
        Club _club = new Club();
        _club.Name = clubModel.Name;
        _club.Description = clubModel.Description;
        _club.isActive = clubModel.isActive;
        _club.isDeleted = clubModel.isDeleted;
        _club.CreatedDate = DateTime.Now;
        _club.CreatedBy = insert first lastname here;

        _club.CreatedBy = User.Identity.

        _context.Clubs.Add(_club);

        await _context.SaveChangesAsync();

        return Ok();
    }

    return View(clubModel);
}

I wish to insert the first name and last name here _club.CreatedBy at this point of the above api end point.

I create my token with this code when I authenticate:

private string generateJwtToken(User user)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var secret = _configRoot.GetValue<string>("JWTSecret");

    _logger.Log(LogLevel.Information, $"JWT Secret from Everleap={secret}");

    var key = Encoding.ASCII.GetBytes(secret);
    var tokenDescriptor = new SecurityTokenDescriptor
                              {
                                  Subject = new ClaimsIdentity(new Claim[]
                                                {
                                                     new Claim(ClaimTypes.Name, user.Id.ToString())
                                                }),
                                  Expires = DateTime.UtcNow.AddMinutes(15),
                                  SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
                              };

    var token = tokenHandler.CreateToken(tokenDescriptor);

    return tokenHandler.WriteToken(token);
}

My details are stored in a jwttoken. Do I go out to that token again and decrypt it on the controller level.

Response body

{
   "id": 0,
   "firstName": "david",
   "lastName": "buckley",
   "username": "davidbuckleyweb@outlook.com",
   "jwtToken":  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IjAiLCJuYmYiOjE2MTY0MzAzNzUsImV4cCI6MTYxNjQzMTI3NSwiaWF0IjoxNjE2NDMwMzc1fQ.P8smaC0PAB5uSrBbI8bbHoc2PKbwIj7mI0jLnBuJz4s",

   "refreshToken": null
}

I figured out that what I need to do is extend my claims so that its stored in the token it self I use the following to encode the token

var tokenDescriptor = new SecurityTokenDescriptor
{    
     Subject = new ClaimsIdentity(new Claim[]
            {
                 new Claim("CreatedBy", user.FirstName.Substring(0,1).ToUpper() + " "  + user.LastName.Substring(0,1).ToUpper()),
                new Claim(ClaimTypes.Email, user.Username),
                new Claim(ClaimTypes.Name, user.FirstName + " " + user.LastName),
                new Claim(ClaimTypes.Role,roles)
            }),
            Expires = DateTime.UtcNow.AddMinutes(15),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };

Then to decode it I use the following.

var authorization = Request.Headers[HeaderNames.Authorization];
if (AuthenticationHeaderValue.TryParse(authorization, out var headerValue))
{
    // we have a valid AuthenticationHeaderValue that has the following details:
     var scheme = headerValue.Scheme;
     var JWTToken = headerValue.Parameter;

     var token = new JwtSecurityToken(jwtEncodedString: JWTToken);
     string name = token.Claims.First(c => c.Type == "CreatedBy").Value;       
    _club.CreatedBy = name;
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM