thisチュートリアルに従って、私のSPA用の簡単なOAuthサーバを作成しています。 OAuthプロバイダからJWTの罰金を請求することができます。しかし、JWTを承認ヘッダー(このように:Authorization Bearer <token>
)に送ると、私はいつも401 "この要求に対して承認が拒否されました"というメッセージが表示されます。ASP.NET JWTベアラ認証でリクエストコンテキストでユーザが変更されない
コードを実行すると、要求コンテキスト内のユーザーがJWTの所有者ではなく匿名のWindows認証ユーザーに設定されていることがわかります。
app.UseWebAPI()
コールをOAuth設定の後に置くと言っている人がたくさんいますが、私はstartup.csにWebAPIを登録していません。私はすべきですか?私は現在、私のコードのどこにでもapp.UseWebAPI()
を持っていません(そして、APIは許可なしでうまくいきます)。
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
}
}
public partial class Startup
{
/// <summary>
/// OAuth configuration
/// </summary>
/// <param name="app"></param>
public void ConfigureOAuth(IAppBuilder app)
{
// Unique identifier for the entity issuing the token
var issuer = ConfigurationManager.AppSettings["issuer"];
// Private key used to secure the token
var secret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["secret"]);
// Enable JWT authentication
app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] { "Any" },
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
}
});
// Create authentication endponit
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/api/login/"),
AccessTokenExpireTimeSpan = TimeSpan.FromHours(1),
Provider = new CustomOAuthProvider(),
AccessTokenFormat = new CustomJwtFormat(issuer)
});
}
}
はここに私のCustomOAuthProviderクラスです:ここで
は私startup.csだpublic class CustomOAuthProvider : OAuthAuthorizationServerProvider
{
IMessengerRepository repo;
public CustomOAuthProvider() : base()
{
repo = new MessengerRepository();
}
public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
// Enable CORS
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
// Check against the repository to see if the login details are correct
var user = repo.Authenticate(context.UserName, context.Password);
// If the login details are incorrect, return an error
if (user == null)
{
context.SetError("invalid_grant", "The username or password is incorrect");
context.Rejected();
return Task.FromResult<object>(null);
}
// Otherwise, return a JWT
var ticket = new AuthenticationTicket(SetClaimsIdentity(context, user), new AuthenticationProperties());
context.Validated(ticket);
return Task.FromResult<object>(null);
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
// Because the audience is not validated, the request is validated straight away without any checks
context.Validated();
return Task.FromResult<object>(null);
}
/// <summary>
/// Create a ClaimsIdentity based on their username and role
/// </summary>
/// <param name="context"></param>
/// <param name="user"></param>
/// <returns></returns>
public static ClaimsIdentity SetClaimsIdentity(OAuthGrantResourceOwnerCredentialsContext context, UserDto user)
{
var identity = new ClaimsIdentity("JWT");
// Add claims for the user themselves
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim("sub", context.UserName));
// Add claim for the user's role
identity.AddClaim(new Claim(ClaimTypes.Role, user.UserRole.RoleName.TrimEnd(' ')));
return identity;
}
}
と私のCustomJwtFormatクラス:
public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket>
{
// Private key for encoding token
private static readonly byte[] secret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["secret"]);
// Entity issuing the token
private readonly string issuer;
public CustomJwtFormat(string issuer)
{
this.issuer = issuer;
}
public string Protect(AuthenticationTicket data)
{
if (data == null)
throw new ArgumentNullException(nameof(data));
var signingKey = new HmacSigningCredentials(secret);
var issued = data.Properties.IssuedUtc;
var expires = data.Properties.ExpiresUtc;
return new JwtSecurityTokenHandler().WriteToken(new JwtSecurityToken(issuer, null, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey));
}
public AuthenticationTicket Unprotect(string protectedText)
{
throw new NotImplementedException();
}
}