[英]Understanding Token Generation/Validation in ASP.NET (MVC, web API)
我正在开发一个 MVC 项目,我正在生成一个令牌来授权任何拥有它的人说著名的“Hello World!”。 由于我是 ASP.NET 中的新手,因此我不了解 WHERE 和 WHO 生成令牌的位置,以及生成后将其保存在何处(或如何)。 此外,一旦我使用令牌启动获取/发布,我也不知道谁会验证令牌。 最终目的是尝试改变生成的令牌类型,获得一个像 JWT 令牌这样的新令牌,而不是基本令牌。 我正在使用 OWIN。
以下是我认为理解所有重要的部分。
using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;
using Owin;
using ExampleToUnderstand.Models;
using ExampleToUnderstand.Providers;
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
var config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseWebApi(config);
}
}
/*Following the partial class Startup.Auth.cs*/
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
var oAuthServerOptions = new OAuthAuthorizationServerOptions()
{
// AuthorizationCodeFormat = new JwtFormat(audienceId, new SymmetricKeyIssuerSecurityTokenProvider(issuer, signingKey)), // da togliere se non funziona
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(3),
Provider = new AuthorizationProvider ()
};
// Token Generation
app.UseOAuthAuthorizationServer(oAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
然后我按照一些指南开发了一个提供程序,结果是这样的:
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Owin.Security.OAuth;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Threading.Tasks;
public class AuthorizationProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
IdentityUser user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim(ClaimTypes.Role, "User"));
context.Validated(identity);
/*WHO GENERATES THE TOKEN HERE?? WHICH IS THE ALGHORITHM USED??*/
}
}
使用 Postman 我得到了这样的结果。
{
"access_token": "mxHZZEFB6pAc6WnTkjeamyxgDMUVNy64CkmtTEwwN2yLZkDQkfDy3J6EIVVLDNRN1-XkeA50Xqk0oB9DEprEuCzGAdsgOG69iPUmf7i7OEZuJfnIXWf0S_qf23gsU5Ppr_lBnpP8pd1RRSQNwvFk_HiumdrJTm91cKenhvWEfbg8a9qhQCH4cwDCzbZ1mwR682WqApk0NOUK7w8UXR7kqIKrS9S2Y4azAvh-9zNWXB3lEkCtoZgDKgLBWotIc9cA8N5FVxd_WOYchA2BYBkgkisZtuW0CigJ4l5Om0zzJJypGGS22foyAdnHFbgkpcIW",
"token_type": "bearer",
"expires_in": 179
}
调用以下方法我得到“Hello World!”。
/*Method inside Homecontroller.cs that extends a controller*/
[Route("/api/HelloWorld")]
[HttpGet]
[Authorize] // How does the authorization works?
public string HelloWorld()
{
return "Hello World";
}
非常好,但我想知道它是如何工作的。 如果有人有建议、文本、有效的书籍/指南来源或其他东西,我将不胜感激!
提前致谢
“此外,一旦我使用令牌启动获取/发布,我也不知道谁会验证令牌。”
我相信在请求处理管道中的某个地方,会进行检查以确定令牌是否有效。 如果您查看 AuthorizeAttribute 的源代码
protected virtual bool IsAuthorized(HttpActionContext actionContext)
{
if (actionContext == null)
{
throw Error.ArgumentNull("actionContext");
}
IPrincipal user = actionContext.ControllerContext.RequestContext.Principal;
if (user == null || user.Identity == null || !user.Identity.IsAuthenticated)
{
return false;
}
if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
{
return false;
}
if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole))
{
return false;
}
return true;
}
用户身份的 IsAuthenticated 属性已设置。 因此,如果您的令牌有效,则 IsAuthenticated 为真。
AuthorizeAttribute 的源代码可以在这里找到https://github.com/aspnet/AspNetWebStack/blob/main/src/System.Web.Http/AuthorizeAttribute.cs
根据这个答案,Web API 在哪里存储生成的令牌以验证后续请求?
它是 OAuthBearerAuthenticationMiddleware 在请求管道的早期阶段消耗您的令牌
在做了一些源代码潜水之后,我发现了一些关于 OAuthBearerAuthenticationOptions 及其属性 AccessTokenFormat 的信息
/// <summary>
/// The data format used to un-protect the information contained in the access token.
/// If not provided by the application the default data protection provider depends on the host server.
/// The SystemWeb host on IIS will use ASP.NET machine key data protection, and HttpListener and other self-hosted
/// servers will use DPAPI data protection. If a different access token
/// provider or format is assigned, a compatible instance must be assigned to the OAuthAuthorizationServerOptions.AccessTokenProvider
/// and OAuthAuthorizationServerOptions.AccessTokenFormat of the authorization server.
/// </summary>
public ISecureDataFormat<AuthenticationTicket> AccessTokenFormat { get; set; }
因此,当您配置 OAuthBearerAuthenticationOptions 时,如果您没有指定 AccessTokenFormat,则将使用默认的。 这取决于您使用的主机。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.