如何解决如何使用JWT令牌ASP.NET MVC
对不起,这是一个很长的信息,但要明确(我希望) 我已遵循此article来设置AuthorizationServerProvider,并让拥有JWT令牌的任何人在我的代码中调用某个API。但是,当我尝试调用我的MVC项目的任何控制器或API控制器方法时,都会收到未授权消息。
This is When I Request the Token (Updated)
This is when I try to Invoke a Method with [authorize attribute]
这是我的ValidateClientAuthentication和GrantResourceOwnerCredentials方法:
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security.OAuth;
using System.Security.Claims;
using System.Threading.Tasks;
using MyProject.Models;
using Microsoft.Owin.Security;
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var allowedOrigin = "*";
//
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin",new[] { allowedOrigin });
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName,context.Password);
if (user == null)
{
context.SetError("invalid_grant","The user name or password is incorrect.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,"JWT"); // maybe this is the problem
// oAuthIdentity.AddClaim(new Claim(ClaimTypes.Role,"User"));
// oAuthIdentity.AddClaim(new Claim(ClaimTypes.Authentication,"AudienceID"));
var ticket = new AuthenticationTicket(oAuthIdentity,null);
context.Validated(ticket);
}
}
在Startup.Auth.cs中,我使用了两种方法来让具有[Authorize]
属性的Api控制器可以通过JWT进行验证。
这里是局部类:
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 partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
ConfigureOAuthTokenGeneration(app);
ConfigureOAuthTokenConsumption(app);
app.UseCookieAuthentication(new CookieAuthenticationoptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,LoginPath = new PathString("/Account/Login"),Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager,ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(10),regenerateIdentity: (manager,user) => user.GenerateUserIdentityAsync(manager))
}
});
/*Other Types of Authentication*/
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie,TimeSpan.FromMinutes(5));
app.UseTwoFactorRememberbrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberbrowserCookie);
}
private void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
//For Dev enviroment only (on production should be AllowInsecureHttp = false)
AllowInsecureHttp = true,TokenEndpointPath = new PathString("/oauth/token"),AccesstokenExpireTimeSpan = TimeSpan.FromMinutes(3),Provider = new AuthorizationServerProvider(),AccesstokenFormat = new CustomJwtFormat("https://localhost:44391")
};
app.USEOAuthAuthorizationServer(OAuthServerOptions);
}
private void ConfigureOAuthTokenConsumption(IAppBuilder app)
{
var issuer = "https://localhost:44391";
string audienceId = ConfigurationManager.AppSettings["AudienceID"]; //its value is "AudienceID"
byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["SecretKey"]);
string[] AllowedAud = new[] { audienceId };
// Api controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationoptions
{
AuthenticationMode = AuthenticationMode.Active,AllowedAudiences = AllowedAud,// IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[],IssuerSecurityKeyProviders = new IIssuerSecurityKeyProvider[]
{
new SymmetricKeyIssuerSecurityKeyProvider(issuer,audienceSecret)
}
}) ;
}
}
我在ConfigureAuth(IAppBuilder app)中调用这些方法。 所以毕竟,我不明白为什么我无法获得授权。有想法吗?
如果这可以帮助您:
我正在使用Microsoft.Owin:Security.Jwt v4.1.1
using Microsoft.Owin.Security;
using System;
using System.Configuration;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket>
{
private readonly string _issuer = string.Empty;
public CustomJwtFormat(string issuer)
{
_issuer = issuer;
}
/*This Generate JWT*/
public string Protect(AuthenticationTicket data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
string username = data.Identity.Name;
string audienceId = ConfigurationManager.AppSettings["AudienceID"]; // "AudienceID"
string symmetricKeyAsBase64 = ConfigurationManager.AppSettings["SecretKey"];
var keyByteArray = Convert.FromBase64String(symmetricKeyAsBase64);
var issued = data.Properties.IssuedUtc;
var expires = data.Properties.ExpiresUtc;
var securityKey = new SymmetricSecurityKey(keyByteArray);
var signingCredentials = new SigningCredentials(securityKey,algorithm: SecurityAlgorithms.HmacSha256Signature);
var token = new JwtSecurityToken(issuer:_issuer,audience: audienceId,data.Identity.Claims,issued.Value.UtcDateTime,expires.Value.UtcDateTime,signingCredentials) ;
var handler = new JwtSecurityTokenHandler();
var jwt = handler.Writetoken(token);
return jwt;
}
public AuthenticationTicket Unprotect(string protectedText)
{
throw new NotImplementedException();
}
}
这是启动
using Microsoft.Owin;
using Owin;
using System.Web.Http;
[assembly: OwinStartupAttribute(typeof(MyProject.Startup))]
namespace MyProject
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
var config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseWebApi(config);
}
}
}
解决方法
除非另有特别配置,否则令牌身份验证中会进行一些强制性检查。
- 令牌是由预期的发行者发行的
- 该令牌用于预期的受众
- 该令牌已由预期的安全密钥签名
您应始终仔细检查1)和2)的配置,并使用https://jwt.ms/之类的令牌查看器来了解有效负载。
从这个角度来看,我可以看到您令牌中的观众是 AudienceId
{
"alg": "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256","typ": "JWT"
}.{
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "199c43cc-c189-4d72-a21e-0c4828f37c8f","http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": "UsernameTest@aaa.com","http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider": "ASP.NET Identity","AspNet.Identity.SecurityStamp": "5cb5b86f-9580-44eb-9a8f-a188262d849d","nbf": 1603013411,"exp": 1603013591,"iss": "https://localhost:44391","aud": "AudienceID"
}.[Signature]
在令牌验证参数中,您说的是
string audienceId = ConfigurationManager.AppSettings["ClientID"];
您已经提到此值为 AccountTest ,但是您的令牌具有值AudienceID。为此,您的应用设置ClientID 必须的值必须是 AudienceID 。确保这两个值匹配-令牌中的aud声明值以及您在配置中为AllowedAudiences设置的值。
您的验证设置必须与令牌有效负载中的设置完全相同,否则请求将被拒绝。您可以在令牌的验证中添加一些日志记录,以准确找出被拒绝的内容,请查看此链接
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。