好的!我想通了,它实际上真的很容易!如果有人需要,我会添加一个长答案。
第 1 步:使用 System.IdentityModel.Tokens.Jwt、Microsoft.AspNet.WebApi.Cors 和 Microsoft.AspNet .Cors
TOKEN 生成。
第 2 步:实现 static class TokenManager,您将在其中生成/验证 TOKEN,并在其中放置您的用户角色。 (Implementation source)
public static class TokenManager
{
private static string Secret = "my_secret_key";
//Use
private static JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
public static string GenerateToken(string username)
{
byte[] key = Convert.FromBase64String(Secret);
var descriptor = GenerateTokenDescriptor(username, key);
JwtSecurityToken token = handler.CreateJwtSecurityToken(descriptor);
return handler.WriteToken(token);
}
private static SecurityTokenDescriptor GenerateTokenDescriptor(string username, byte[] key)
{
SymmetricSecurityKey securityKey = new SymmetricSecurityKey(key);
SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[] {
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.Role, "Role1"),//<-- User role!
new Claim(ClaimTypes.Role, "Role2")}),//<-- User role!
Expires = DateTime.UtcNow.AddMinutes(30),//Token takes only UTC time
SigningCredentials = new SigningCredentials(securityKey,
SecurityAlgorithms.HmacSha256Signature)
};
return descriptor;
}
public static ClaimsPrincipal GetPrincipal(string token)
{
try
{
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = (JwtSecurityToken)tokenHandler.ReadToken(token);
if (jwtToken == null)
return null;
byte[] key = Convert.FromBase64String(Secret);
TokenValidationParameters parameters = new TokenValidationParameters()
{
RequireExpirationTime = true,
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = new SymmetricSecurityKey(key)
};
SecurityToken securityToken;
ClaimsPrincipal principal = tokenHandler.ValidateToken(token,
parameters, out securityToken);
return principal;
}
catch (Exception e)
{
return null;
}
}
}
注意:我使用此代码生成了my_secret_key:
HMACSHA256 hmac = new HMACSHA256();
string key = Convert.ToBase64String(hmac.Key);
第 3 步:创建将用于授权的自定义属性。
public class MyAuthorizeAttribute : AuthorizeAttribute
{
private readonly string[] allowedroles;
public MyAuthorizeAttribute(params string[] roles)
{
this.allowedroles = roles;
}
protected override bool IsAuthorized(HttpActionContext actionContext)
{
//Default outcome
bool authorize = false;
//Get TOKEN
var authToken = actionContext.Request.Headers.Authorization?.Parameter;
//Check if TOKEN has parameters
if (authToken != null)
{
//Get roles from TOKEN
List<string> userRoles = TokenManager.GetPrincipal(authToken).FindAll(ClaimTypes.Role).Select(x => x.Value).ToList();
//Check if any of User Roles is allowed
authorize = this.allowedroles.Any(x => userRoles.Any(y => y == x));
}
//return outcome
return authorize;
}
}
第 4 步:在 Controller
中使用您的属性
public class HomeController : ApiController
{
List<string> myList = new List<string>
{
"Element1",
"Element2",
"Element3"
};
[MyAuthorizeAttribute("Role2")]//Add roles names in parameter
[HttpGet]
[Route("api/mylist")]
public List<string> MyList()
{
return this.myList;
}
[HttpPost]
[Route("api/login")]
public HttpResponseMessage Login()
{
var myToken = TokenManager.GenerateToken("username");
return Request.CreateResponse(HttpStatusCode.OK, myToken);
}
}
第 5 步:将 TOKEN 保存到 LOCAL STORAGE:
fetch('https://localhost:XXXXX/api/login', {
method: 'post',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
}).then(x => {
x.json().then(y => {
localStorage.setItem('TOKEN', y);
});
}).catch(err => {
console.log(err);
});
第 6 步:最后,在您的请求的 标头中传递您的 TOKEN:
fetch('https://localhost:XXXXX/api/mylist', {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('TOKEN'),
'Access-Control-Allow-Origin': '*'
},
}).then(x => {
console.log(x.json());//Outcome from API
}).catch(err => {
console.log(err);
});
完成,应该可以正常工作了。