添加授权时缺少身份验证方案
Posted
技术标签:
【中文标题】添加授权时缺少身份验证方案【英文标题】:Authentication scheme missing when adding authorize 【发布时间】:2020-10-13 00:45:20 【问题描述】:错误:没有指定 authenticationScheme,也没有找到 DefaultChallengeScheme。
我正在创建两个应用程序:WebApi,这项工作我遵循教程:WebApi Core
在运行邮递员时,这很好用。我遇到的问题是尝试创建使用 web api 的 asp.net 核心,我正在关注本教程:Client Side
所以这就是我所拥有的
两个控制器HomeController、AccountController
帐户控制器
public class AccountController : Controller
[HttpGet]
public IActionResult Login()
return View();
[HttpPost]
[AutoValidateAntiforgeryToken]
public IActionResult Login(AuthenticatedUser user)
string baseUrl = "http://localhost:8080";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(baseUrl);
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
AuthenticatedUser userModel = new AuthenticatedUser();
userModel.Username = user.Username;
userModel.Password = user.Password;
string stringData = JsonConvert.SerializeObject(userModel);
var contentData = new StringContent(stringData, System.Text.Encoding.UTF8, "application/json");
HttpResponseMessage response = client.PostAsync("/Token", contentData).Result;
string stringJWT = response.Content.ReadAsStringAsync().Result;
JWT jwt = JsonConvert.DeserializeObject<JWT>(stringJWT);
HttpContext.Session.SetString("token", jwt.Token);
ViewBag.Message = "User logged in successfully!";
return View("Index");
HomeController(没什么特别的,除了我在开始时添加了授权)
[Authorize]
public class HomeController : Controller
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
_logger = logger;
...
在我的 startup.cs 上
ConfigureServices 方法
services.AddMemoryCache();
services.AddSession();
services.AddAuthentication(options =>
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
)
.AddCookie(options =>
options.LoginPath = "/Account/Login/";
// options.AccessDeniedPath = "/Account/Forbidden/";
);
并在配置方法中添加了一些方法
app.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
不确定我缺少什么,我安装了以下软件包,不知道是否缺少一些。
Microsoft.AspNet.WebApi.Client Microsoft.AspNetCore.Authentication.OpenIDConnect System.IdentityModel.Tokens.Jwt我必须说,仅当我将属性 [Authorize] 放在家庭控制器上时才会出现问题(没有尝试任何其他位置,但我感觉我缺少绑定授权属性和方案的东西,但我没有当然)。
【问题讨论】:
作为我的假设,HomeController 是一个 Web 应用程序,不是吗?您正在尝试从“/Token”中检索 JWT,然后将其保存到 Session 中。在客户端,您尝试在用户获得 JWT 令牌后访问 Home,对吗?。 是的,正确 因此您必须将此令牌保存到 Cookie 而不是 Session,因为您的身份验证方案是基于 Cookie 的。你可以喜欢这个代码github.com/onelogin/openid-connect-dotnet-core-sample/blob/…,让你清楚如何使用Cookie和OpenId。 如果我没记错的话,你是在'/Token'中做self-JWT,对吧?实际上,JWT 仅用于通过附加 Authorization Header 来执行 Web API。在基于 Web 的场景中,您应该通过调用 HttpContext.SignInAsync() 而不是 JWT 来使用基于 Cookie。但如果您仍想使用 JWT 和 Session,您可以更改 options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme 并使用此主题 docs.microsoft.com/en-us/aspnet/core/signalr/… 和 OnMessageReceived 事件在 Request.Session 中检索 jwt 令牌 你是正确的“令牌”返回一个生成的 JWT 令牌,我在 api 上使用授权时用于验证,是的,在客户端使用 cookie 进行验证是有意义的,我正在尝试了解您发送给我的内容,谢谢 【参考方案1】:对于您的客户端,您的启动看起来不错。
您应该使用 HttpContext.SignInAsync() 并使用 Cookie 存储您的令牌,因为您的身份验证方案是基于 cookie 的。
因此,例如,在使用 JWT 时,通常您有与之关联的声明。您将需要这些声明来构建 ClaimsPrincipal 对象以便登录。请参阅下面的更新代码:
注意:切勿在异步方法上使用“.Result”。另外,请考虑使用 IHttpClientFactory 而不是自己直接创建 HttpClient。
[HttpPost]
[AutoValidateAntiforgeryToken]
public async Task<IActionResult> Login(AuthenticatedUser user)
// This section should be essentially removed. Use IHttpClientFactory
string baseUrl = "http://localhost:8080";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(baseUrl);
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
string stringData = JsonConvert.SerializeObject(user);
var contentData = new StringContent(stringData, System.Text.Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync("/Token", contentData);
if (response.IsSuccessStatusCode)
string stringJWT = await response.Content.ReadAsStringAsync();
JWT jwt = JsonConvert.DeserializeObject<JWT>(stringJWT);
var userIdentity = new ClaimsIdentity(token.Claims, CookieAuthenticationDefaults.AuthenticationScheme);
var userPrincipal = new ClaimsPrincipal(userIdentity);
// This line here fixes your main issue
await HttpContext.SignInAsync(userPrincipal);
HttpContext.Response.Cookies.Append("token", jwt.Token);
ViewBag.Message = "User logged in successfully!";
return View("Index");
反序列化令牌的注意事项,您也可以使用它:
public JwtSecurityToken GetDecodedToken(string token)
return new JwtSecurityTokenHandler( ).ReadJwtToken(token);
【讨论】:
以上是关于添加授权时缺少身份验证方案的主要内容,如果未能解决你的问题,请参考以下文章