Я пытаюсь преобразовать токен JWT Azure Active Directory в объект ClaimsPrincipal точно так же, как это делает ASP.NET Core.
После некоторого поиска в Google я нашел JwtSecurityTokenHandler
(в System.IdentityModel.Tokens.Jwt
и использовал этодля декодирования строки.
var token = "eyj0..."
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadJwtToken(token);
var claims = jsonToken.Claims;
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "aad"));
Это преобразовывает токен JWT, но при дальнейшей проверке я обнаружил несколько критических различий в объекте ClaimsPrincipal
, созданном выше, и объекте ClaimsPrincipal
, созданном ASP.NETЯдро анализируется с того же токена.
(важная часть) JSON-сериализованный ClaimsPrincipal.Identity
объект, созданный ASP.NET:
{
"$id": "2",
"AuthenticationType": "aad",
"IsAuthenticated": true,
"Actor": null,
"BootstrapContext": null,
"Claims": [
...
{
"$id": "13",
"Issuer": "LOCAL AUTHORITY",
"OriginalIssuer": "LOCAL AUTHORITY",
"Properties": {
},
"Subject": {
"$ref": "2"
},
"Type": "http:\/\/schemas.xmlsoap.org\/ws\/2005\/05\/identity\/claims\/emailaddress",
"Value": "<MY EMAIL>",
"ValueType": "http:\/\/www.w3.org\/2001\/XMLSchema#string"
}
...
],
"Label": null,
"Name": "<MY EMAIL>",
"NameClaimType": "http:\/\/schemas.xmlsoap.org\/ws\/2005\/05\/identity\/claims\/emailaddress",
"RoleClaimType": "http:\/\/schemas.microsoft.com\/ws\/2008\/06\/identity\/claims\/role"
}
(важная часть) JSON-сериализованногоClaimsPrincipal.Identity
объект, созданный JwtSecurityTokenHandler
:
{
"$id": "2",
"AuthenticationType": "aad",
"IsAuthenticated": true,
"Actor": null,
"BootstrapContext": null,
"Claims": [
...
{
"$id": "13",
"Issuer": "https:\/\/sts.windows.net\/<AN GUID>\/",
"OriginalIssuer": "https:\/\/sts.windows.net\/<AN GUID>\/",
"Properties": {
},
"Subject": {
"$ref": "2"
},
"Type": "email",
"Value": "<MY EMAIL>",
"ValueType": "http:\/\/www.w3.org\/2001\/XMLSchema#string"
}
...
],
"Label": null,
"Name": null,
"NameClaimType": "http:\/\/schemas.xmlsoap.org\/ws\/2005\/05\/identity\/claims\/name",
"RoleClaimType": "http:\/\/schemas.microsoft.com\/ws\/2008\/06\/identity\/claims\/role"
}
Существует 4 основных различия в 2 сериализованных объектах.
- Все претензии имеют
Issuer
из LOCAL AUTHORITY
для токена, декодированного с помощью JwtSecurityTokenHandler
, где ASP.NET дает https:\/\/sts.windows.net\/<AN GUID>\/
. - Значения
Type
некоторых утверждений различны. Как вы можете видеть Type
утверждения, содержащегоадрес электронной почты пользователя email
для токена, декодированного JwtSecurityTokenHandler
, где ASP.NET дает http:\/\/schemas.xmlsoap.org\/ws\/2005\/05\/identity\/claims\/emailaddress
. NameClaimType
объекта ClaimsPrincipal.Identity
, декодированного с помощью JwtSecurityTokenHandler
, равно http:\/\/schemas.xmlsoap.org\/ws\/2005\/05\/identity\/claims\/name
, где ASP.net дает http:\/\/schemas.xmlsoap.org\/ws\/2005\/05\/identity\/claims\/emailaddress
. - (возможно, из-за разницы 2 и 3)
Name
объекта ClaimsPrincipal.Identity
, декодируемого JwtSecurityTokenHandler
, равно null
Как правильно преобразовать токенТаким образом, полученный ClaimsPrincipal
объект идентичен тому, который генерирует ядро ASP.NET?