【发布时间】:2021-01-31 10:08:15
【问题描述】:
抱歉,这是一条很长的信息,但要清楚(我希望) 我已经按照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);
}
}
}
【问题讨论】:
-
您可以将您的令牌显示为文本吗?
-
我用新的 JWT 令牌示例编辑了帖子 =)。 jwt.io 它告诉我这是一个无效的签名!
-
你能显示
Startup.cs代码吗? -
@Julián 我已将其添加到问题中
标签: c# asp.net asp.net-mvc asp.net-web-api jwt