![](/img/trans.png)
[英]WCF service client configuration from appsetting.json (.NET Core)
[英]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.