繁体   English   中英

在 .net core 3.1 中使用来自 appsetting.json 的凭据时,授权不起作用

[英]Authorization not working when using credentials from appsetting.json in .net core 3.1

我是 C# 的新手,过去 5 天一直在努力使用基于令牌的授权。 当我传递硬编码的用户名和密码时,我的授权正在工作,但是当我从我的授权访问用户名和密码时,我的授权不起作用。

这是我的 appsetting.json,我在其中提到了用户名、密码和密钥

{"UserCred":{
  "Username":"test",
  "Password":"test"
},
  
  "AppSettings": {
    "Secret": "This is my secret key"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

这是我的 UserService.cs,我在其中访问来自 appsetting.json 的值并生成令牌。 当我在私有列表对象授权中传递硬编码值时工作正常,并且从 appsetting 访问时它不起作用帮助我访问私有列表对象中的值,如果我在那里访问这些值,它将起作用。

服务\用户服务.cs

using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using loginApi.Helpers;
using loginApi.Models;
using Microsoft.Extensions.Configuration;

namespace loginApi.Services
{
    public interface IUserService
    {
        AuthenticateResponse Authenticate(AuthenticateRequest model);
        IEnumerable<User> GetAll();
        User GetById(string username);
    }

    public class UserService : IUserService
    {
        
        private List<User> _users = new List<User>
        {
           // new User { Username = "test", Password = "test" }
        };

        private readonly AppSettings _appSettings;
       
        private readonly IConfiguration _configuration;

        public UserService(IOptions<AppSettings> appSettings,IConfiguration configuration)
        {
            _appSettings = appSettings.Value;
            _configuration = configuration;
        }

        public AuthenticateResponse Authenticate(AuthenticateRequest model)
        {
                 var _username = _configuration.GetSection("UserCred").GetSection("Username").Value;
                 var _Password = _configuration.GetSection("UserCred").GetSection("Password").Value;
        
                
                   Console.WriteLine(_username.ToString());
                   Console.WriteLine(_Password.ToString());
                   
                     _users = new List<User> 
                { 
                    new User { Username = _username.ToString(), Password = _Password.ToString()}
                };

            var user = _users.SingleOrDefault(x => x.Username == model.Username && x.Password == model.Password);

            
            if (user == null) return null;

           
            var token = generateJwtToken(user);

            return new AuthenticateResponse(user, token);
        }

        public IEnumerable<User> GetAll()
        {
            return _users;
        }

        public User GetById(string username)
        {
            return _users.FirstOrDefault(x => x.Username== username);
        }

   

        private string generateJwtToken(User user)
        {
            
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[] { new Claim("username", user.Username.ToString()) }),
                Expires = DateTime.UtcNow.AddDays(7),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }
    }
}

我附上整个代码以供参考

控制器\UsersController.cs

using Microsoft.AspNetCore.Mvc;
using loginApi.Models;
using loginApi.Services;

namespace loginApi.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class UsersController : ControllerBase
    {
        private IUserService _userService;

        public UsersController(IUserService userService)
        {
            _userService = userService;
        }

        [HttpPost("authenticate")]
        public IActionResult Authenticate(AuthenticateRequest model)
        {
            var response = _userService.Authenticate(model);

            if (response == null)
                return BadRequest(new { message = "Username or password is incorrect" });

            return Ok(response);
        }

        [Authorize]
        [HttpGet]
        public IActionResult GetAll()
        {
            var users = _userService.GetAll();
            return Ok(users);
        }
    }
}

Helpers\AuthorizeAttribute.cs

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using loginApi.Models;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeAttribute : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var user = (User)context.HttpContext.Items["User"];
        if (user == null)
        {
            
            context.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized };
        }
    }
}

Helpers\JWTMiddleware.cs

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using loginApi.Services;
using loginApi.Models;

namespace loginApi.Helpers
{
    public class JwtMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly AppSettings _appSettings;

        public JwtMiddleware(RequestDelegate next, IOptions<AppSettings> appSettings)
        {
            _next = next;
            _appSettings = appSettings.Value;
        }

        public async Task Invoke(HttpContext context, IUserService userService)
        {
            var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();

            if (token != null)
                attachUserToContext(context, userService, token);

            await _next(context);
        }

        private void attachUserToContext(HttpContext context, IUserService userService, string token)
        {
            try
            {
                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
                tokenHandler.ValidateToken(token, new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ClockSkew = TimeSpan.Zero
                }, out SecurityToken validatedToken);

                var jwtToken = (JwtSecurityToken)validatedToken;
                //var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value);
                var userName = jwtToken.Claims.First(x => x.Type == "username").Value;
                
                context.Items["User"] = userService.GetById(userName);
            }
            catch
            {
                
            }
        }
    }
}

模型\Appsettings.cs

namespace loginApi.Models
{
    public class AppSettings
    {
        public string Secret { get; set; }
    }
}

模型\用户.cs

using System.Text.Json.Serialization;

namespace loginApi.Models
{
    public class User
    {
        public string Username { get; set; }

        [JsonIgnore]
        public string Password { get; set; }
    }
}

模型\AuthenticateRequest.cs

using System.ComponentModel.DataAnnotations;

namespace loginApi.Models
{
    public class AuthenticateRequest
    {
        [Required]
        public string Username { get; set; }

        [Required]
        public string Password { get; set; }
    }
}

模型\验证响应.cs

using loginApi.Models;

namespace loginApi.Models
{
    public class AuthenticateResponse
    {
       
        public string Username { get; set; }
        public string Token { get; set; }


        public AuthenticateResponse(User user, string token)
        {            
            Username = user.Username;
            Token = token;
        }
    }
}

尝试这样做。

  public UserService(IOptions<AppSettings> appSettings,IConfiguration configuration)
  {
        _appSettings = appSettings.Value;
        _configuration = configuration;
       var _username = _configuration.GetSection("UserCred").GetSection("Username").Value;
       var _Password = _configuration.GetSection("UserCred").GetSection("Password").Value;
       
      Console.WriteLine(_username.ToString());
      Console.WriteLine(_Password.ToString());
               
      _users = new List<User> 
      { 
         new User { Username = _username.ToString(), Password = _Password.ToString()}
      };
    }

    public AuthenticateResponse Authenticate(AuthenticateRequest model)
    { 
        var user = _users.SingleOrDefault(x => x.Username == model.Username && x.Password == model.Password);

        
        if (user == null) return null;

       
        var token = generateJwtToken(user);

        return new AuthenticateResponse(user, token);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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