Dan Çalışma Matt Dekrey muhteşem cevap , ben ASP.NET Çekirdek (1.0.1) karşı çalışan, belirteci tabanlı kimlik doğrulama bir dolu çalışma örneği oluşturduk. Kodun tamamını GitHub'daki ( 1.0.0-rc1 , beta8 , beta7 için alternatif dallar ) bu depoda bulabilirsiniz , ancak kısaca önemli adımlar şunlardır:
Uygulamanız için bir anahtar oluşturun
Örneğimde, uygulama her başlatıldığında rastgele bir anahtar oluşturuyorum, bir tane oluşturmanız ve bir yerde saklamanız ve uygulamanıza sağlamanız gerekir. Nasıl rastgele bir anahtar oluşturduğum ve bir .json dosyasından nasıl içe aktarabileceğiniz için bu dosyaya bakın . @Kspearrin tarafından yapılan yorumlarda da belirtildiği gibi, Veri Koruma API'sı anahtarları "doğru" yönetmek için ideal bir aday gibi görünüyor, ancak bu mümkün ise henüz çalışmadım. Çalışırsanız lütfen bir çekme isteği gönderin!
Startup.cs - ConfigureServices
Burada, belirteçlerimizin imzalanması için özel bir anahtar yüklememiz gerekir; bu anahtarlar, belirtildikçe belirteçleri doğrulamak için de kullanacağız. Anahtarı, key
aşağıdaki Yapılandırma yönteminde yeniden kullanacağımız sınıf düzeyinde bir değişkende saklıyoruz . TokenAuthOptions , anahtarlarımızı oluşturmak için TokenController'da ihtiyaç duyacağımız imza kimliğini, kitleyi ve yayıncıyı barındıran basit bir sınıftır.
// Replace this with some sort of loading from config / file.
RSAParameters keyParams = RSAKeyUtils.GetRandomKey();
// Create the key, and a set of token options to record signing credentials
// using that key, along with the other parameters we will need in the
// token controlller.
key = new RsaSecurityKey(keyParams);
tokenOptions = new TokenAuthOptions()
{
Audience = TokenAudience,
Issuer = TokenIssuer,
SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.Sha256Digest)
};
// Save the token options into an instance so they're accessible to the
// controller.
services.AddSingleton<TokenAuthOptions>(tokenOptions);
// Enable the use of an [Authorize("Bearer")] attribute on methods and
// classes to protect.
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
Ayrıca [Authorize("Bearer")]
korumak istediğimiz uç noktalar ve sınıflarda kullanmamıza izin vermek için bir yetkilendirme politikası oluşturduk .
Startup.cs - Yapılandır
Burada, JwtBearerAuthentication'ı yapılandırmamız gerekiyor:
app.UseJwtBearerAuthentication(new JwtBearerOptions {
TokenValidationParameters = new TokenValidationParameters {
IssuerSigningKey = key,
ValidAudience = tokenOptions.Audience,
ValidIssuer = tokenOptions.Issuer,
// When receiving a token, check that it is still valid.
ValidateLifetime = true,
// This defines the maximum allowable clock skew - i.e.
// provides a tolerance on the token expiry time
// when validating the lifetime. As we're creating the tokens
// locally and validating them on the same machines which
// should have synchronised time, this can be set to zero.
// Where external tokens are used, some leeway here could be
// useful.
ClockSkew = TimeSpan.FromMinutes(0)
}
});
TokenController
Belirteç denetleyicisinde, Startup.cs dosyasına yüklenen anahtarı kullanarak imzalı anahtarlar oluşturmak için bir yönteminiz olması gerekir. Başlangıçta bir TokenAuthOptions örneği kaydettik, bu yüzden bunu TokenController için yapıcıya enjekte etmemiz gerekiyor:
[Route("api/[controller]")]
public class TokenController : Controller
{
private readonly TokenAuthOptions tokenOptions;
public TokenController(TokenAuthOptions tokenOptions)
{
this.tokenOptions = tokenOptions;
}
...
Ardından, giriş bitiş noktası için işleyicinizde jetonu oluşturmanız gerekir, örneğimde bir kullanıcı adı ve şifre alıyorum ve bir if ifadesi kullanarak bunları onaylıyorum, ancak yapmanız gereken temel şey bir hak talebi oluşturmak veya yüklemek tabanlı kimlik ve bunun için jeton oluşturun:
public class AuthRequest
{
public string username { get; set; }
public string password { get; set; }
}
/// <summary>
/// Request a new token for a given username/password pair.
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
[HttpPost]
public dynamic Post([FromBody] AuthRequest req)
{
// Obviously, at this point you need to validate the username and password against whatever system you wish.
if ((req.username == "TEST" && req.password == "TEST") || (req.username == "TEST2" && req.password == "TEST"))
{
DateTime? expires = DateTime.UtcNow.AddMinutes(2);
var token = GetToken(req.username, expires);
return new { authenticated = true, entityId = 1, token = token, tokenExpires = expires };
}
return new { authenticated = false };
}
private string GetToken(string user, DateTime? expires)
{
var handler = new JwtSecurityTokenHandler();
// Here, you should create or look up an identity for the user which is being authenticated.
// For now, just creating a simple generic identity.
ClaimsIdentity identity = new ClaimsIdentity(new GenericIdentity(user, "TokenAuth"), new[] { new Claim("EntityID", "1", ClaimValueTypes.Integer) });
var securityToken = handler.CreateToken(new Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor() {
Issuer = tokenOptions.Issuer,
Audience = tokenOptions.Audience,
SigningCredentials = tokenOptions.SigningCredentials,
Subject = identity,
Expires = expires
});
return handler.WriteToken(securityToken);
}
Ve bu olmalı. [Authorize("Bearer")]
Korumak istediğiniz herhangi bir yönteme veya sınıfa eklemeniz yeterlidir ve bir belirteç olmadan erişmeye çalışırsanız bir hata almalısınız. 500 hatası yerine 401 döndürmek istiyorsanız, burada örneğimde olduğu gibi özel bir özel durum işleyicisi kaydetmeniz gerekir .