Đã chỉnh sửa để làm cho bản chỉnh sửa tương thích với ASP.NET Core 2.0.
Thứ nhất, một số gói NuGet:
- Microsoft.AspNetCore.Authentication.JwtBearer
- Microsoft.AspNetCore.Identity
- System.IdentityModel.Tokens.Jwt
- System.Security .Cryptography.Csp
Th vi một số đối tượng truyền dữ liệu cơ bản.
// Presumably you will have an equivalent user account class with a user name.
public class User
{
public string UserName { get; set; }
}
public class JsonWebToken
{
public string access_token { get; set; }
public string token_type { get; set; } = "bearer";
public int expires_in { get; set; }
public string refresh_token { get; set; }
}
Nhập chức năng phù hợp, bạn cần có phương thức web đăng nhập/mã thông báo để gửi mã thông báo ủy quyền cho người dùng.
[Route("api/token")]
public class TokenController : Controller
{
private ITokenProvider _tokenProvider;
public TokenController(ITokenProvider tokenProvider) // We'll create this later, don't worry.
{
_tokenProvider = tokenProvider;
}
public JsonWebToken Get([FromQuery] string grant_type, [FromQuery] string username, [FromQuery] string password, [FromQuery] string refresh_token)
{
// Authenticate depending on the grant type.
User user = grant_type == "refresh_token" ? GetUserByToken(refresh_token) : GetUserByCredentials(username, password);
if (user == null)
throw new UnauthorizedAccessException("No!");
int ageInMinutes = 20; // However long you want...
DateTime expiry = DateTime.UtcNow.AddMinutes(ageInMinutes);
var token = new JsonWebToken {
access_token = _tokenProvider.CreateToken(user, expiry),
expires_in = ageInMinutes * 60
};
if (grant_type != "refresh_token")
token.refresh_token = GenerateRefreshToken(user);
return token;
}
private User GetUserByToken(string refreshToken)
{
// TODO: Check token against your database.
if (refreshToken == "test")
return new User { UserName = "test" };
return null;
}
private User GetUserByCredentials(string username, string password)
{
// TODO: Check username/password against your database.
if (username == password)
return new User { UserName = username };
return null;
}
private string GenerateRefreshToken(User user)
{
// TODO: Create and persist a refresh token.
return "test";
}
}
Bạn có thể nhận thấy việc tạo mã thông báo vẫn chỉ là "ma thuật" được chuyển bởi một số ITokenProvider tưởng tượng. Xác định giao diện nhà cung cấp mã thông báo.
public interface ITokenProvider
{
string CreateToken(User user, DateTime expiry);
// TokenValidationParameters is from Microsoft.IdentityModel.Tokens
TokenValidationParameters GetValidationParameters();
}
Tôi đã triển khai tạo mã thông báo bằng khóa bảo mật RSA trên JWT. Vì vậy ...
public class RsaJwtTokenProvider : ITokenProvider
{
private RsaSecurityKey _key;
private string _algorithm;
private string _issuer;
private string _audience;
public RsaJwtTokenProvider(string issuer, string audience, string keyName)
{
var parameters = new CspParameters { KeyContainerName = keyName };
var provider = new RSACryptoServiceProvider(2048, parameters);
_key = new RsaSecurityKey(provider);
_algorithm = SecurityAlgorithms.RsaSha256Signature;
_issuer = issuer;
_audience = audience;
}
public string CreateToken(User user, DateTime expiry)
{
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
ClaimsIdentity identity = new ClaimsIdentity(new GenericIdentity(user.UserName, "jwt"));
// TODO: Add whatever claims the user may have...
SecurityToken token = tokenHandler.CreateJwtSecurityToken(new SecurityTokenDescriptor
{
Audience = _audience,
Issuer = _issuer,
SigningCredentials = new SigningCredentials(_key, _algorithm),
Expires = expiry.ToUniversalTime(),
Subject = identity
});
return tokenHandler.WriteToken(token);
}
public TokenValidationParameters GetValidationParameters()
{
return new TokenValidationParameters
{
IssuerSigningKey = _key,
ValidAudience = _audience,
ValidIssuer = _issuer,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromSeconds(0) // Identity and resource servers are the same.
};
}
}
Vì vậy, bây giờ bạn đang tạo mã thông báo. Thời gian để thực sự xác nhận và kết nối nó. Truy cập Startup.cs của bạn.
Trong ConfigureServices()
var tokenProvider = new RsaJwtTokenProvider("issuer", "audience", "mykeyname");
services.AddSingleton<ITokenProvider>(tokenProvider);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = tokenProvider.GetValidationParameters();
});
// This is for the [Authorize] attributes.
services.AddAuthorization(auth => {
auth.DefaultPolicy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build();
});
Sau đó Configure()
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
// Whatever else you're putting in here...
app.UseMvc();
}
Đó nên là về tất cả các bạn cần. Hy vọng rằng tôi đã không bỏ lỡ bất cứ điều gì.
Kết quả là hạnh phúc ...
[Authorize] // Yay!
[Route("api/values")]
public class ValuesController : Controller
{
// ...
}
Tôi rất thích xem mẫu này. –
Bản sắc được tách riêng khỏi cơ chế JWT. Đọc [this] (https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x) và [this] (https://pioneercode.com/post/ xác thực-trong-một-asp-dot-net-core-api-phần-3-json-web-token). Lời chào hỏi. –