Как проверить id_token, полученный asp.net mvc OWIN от Azure AD B2C - PullRequest
1 голос
/ 06 апреля 2019

У нас есть требование безопасности, что мы должны проверить токен id, который мы получаем от Azure AD B2C.Нам нужно проверить их как минимум

customSecurityLevel , аудитория , не ранее и "время истечения", эмитент, nonce

Глядя на промежуточное ПО MVC OWIN asp.net, я заметил, что OpenIdConnectAuthenicationOptions предоставляет следующие возможности:

return new OpenIdConnectAuthenticationOptions
            {
                ...
                Notifications = new OpenIdConnectAuthenticationNotifications //Specifies events which the OpenIdConnectAuthenticationMiddleware invokes to enable developer control over the authentication process.
                {
                    AuthenticationFailed = this.AuthenticationFailed,
                    RedirectToIdentityProvider = this.RedirectToIdentityProvider,
                    AuthorizationCodeReceived = this.OnAuthorizationCodeReceived,
                },

                TokenValidationParameters = new TokenValidationParameters
                {
                    SaveSigninToken = true,           // Important to save the token in boostrapcontext
                    ValidateAudience = true,          // Validate the Audience
                    ValidateIssuer = true,            // Validate the Issuer
                    ValidateLifetime = true,          // Validate the tokens lifetime
                    ValidIssuer = Issuer,             // The issuer to be validated
                    ValidAudience = ClientId,          // The Audience to be validated
                },
            };

Будучи тихим новичком в OWIN, я пытаюсь понять следующее:

  1. Проверяет ли промежуточное ПО OWIN магический токен, который мы получаем от Azure AD B2C, или нам нужно вручную выполнить проверку в соответствии с этим: https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-webapi-manual-jwt-validation/

  2. В какой момент времени должна происходить проверка токенат.е. событие AuthorizationCodeReceived или контроллер / действие перенаправления (страница), настроенное для URL-адреса перенаправления Azure AD B2C?

  3. Нам необходимо проверить больше атрибутов, которые поддерживает TokenValidationParameters, например, customSecurityAttribute, который мы отправляем при начальной загрузке.Есть ли способ продлить это?

  4. Как мы можем проанализировать токен, который мы получаем от Azure AD B2C, используя OWIN?

Подойдет любой пример кода.

1 Ответ

1 голос
/ 06 апреля 2019

, чтобы сделать ваш вопрос проще.

Идея, лежащая в основе токена, состоит в том, чтобы проанализировать токен и получить 3 части из токена

-Header : contain information about in which algorithm the token haven been encrypted

-Payload : information about the user

-Signature: it's the calculation of encryption of ( Header + Payload) using the Azure certificate or( your identity provider).

Следующий шаг - пользователь отправляет запрос на ваш сервер вместе с JWT.

Ваш бэкэнд проанализирует токен и получит тип сертификата, а затем отправит HTTP-запрос вашему провайдеру идентификации для получения сертификата

Затем ваш бэкэнд создаст опцию сертификата и попытается выполнить шифрование для (заголовка + полезной нагрузки), полученной из вашего токена, выходная строка должна быть точно такой же подписи, которую вы получили в токене от вашего внешнего интерфейса.

Если все хорошо теперь ваш бэкэнд начнет проверять другие атрибуты, такие как Аудитория, Эмитент если вы настраиваете свой токен для проверки аудитории, это означает, что ваш интерфейс должен предоставить токену, содержащему аудиторию (идентификатор приложения), точно такую ​​же, как для вашего сервера, так и для эмитента.

вопрос теперь, как мой сервер знает о сертификате? Azure AD с использованием OpenID connect, Дополнительная информация здесь так как вы настроили своего арендатора в бэкэнде, пакет auth позвонит по номеру https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration, чтобы узнать подробности о вашем провайдере идентификации и одна важная ссылка - ("jwks_uri": "https://login.microsoftonline.com/common/discovery/keys"), где размещена подпись. Вы можете прочитать и узнать больше о том, как проверить сертификат JWT и проверить это https://codereview.stackexchange.com/questions/70005/authentication-with-jwt

переход к части 2 проверки дополнительных атрибутов. Так как вы используете OpenIdConnect, пакет имеет класс OpenIdConnectEvents, который позволяет запускать события и делать все, что вы захотите, как это

.AddOpenIdConnect(o =>
    {
        //Additional config snipped
        o.Events = new OpenIdConnectEvents
        {
            OnTokenValidated = async ctx =>
            {
                //Get user's immutable object id from claims that came from Azure AD
                string oid = ctx.Principal.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");

                //Get EF context
                var db = ctx.HttpContext.RequestServices.GetRequiredService<AuthorizationDbContext>();

                //Check is user a super admin
                bool isSuperAdmin = await db.SuperAdmins.AnyAsync(a => a.ObjectId == oid);
                if (isSuperAdmin)
                {
                    //Add claim if they are
                    var claims = new List<Claim>
                    {
                        new Claim(ClaimTypes.Role, "superadmin")
                    };
                    var appIdentity = new ClaimsIdentity(claims);

                    ctx.Principal.AddIdentity(appIdentity);
                }
            }
        };
});

переход к части 3 разбор токена в javascript

function parseJwt (token) {
            var base64Url = token.split('.')[1];
            var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
            return JSON.parse(window.atob(base64));
};

разбор токена в C #

используйте эту библиотеку https://www.jsonwebtoken.io/

try {
  string jsonPayload = JWT.JsonWebToken.Decode(token, secretKey);
  Console.WriteLine(jsonPayload);
} catch (JWT.SignatureVerificationException) {
  Console.WriteLine("Invalid token!");
}

или руководство

var jwtHandler = new JwtSecurityTokenHandler();
var jwtInput = txtJwtIn.Text;

//Check if readable token (string is in a JWT format)
var readableToken = jwtHandler.CanReadToken(jwtInput);

if(readableToken != true)
{
  txtJwtOut.Text = "The token doesn't seem to be in a proper JWT format.";
}
if(readableToken == true)
{
  var token = jwtHandler.ReadJwtToken(jwtInput);

  //Extract the headers of the JWT
  var headers = token.Header;
  var jwtHeader = "{";
  foreach(var h in headers)
  {
    jwtHeader += '"' + h.Key + "\":\"" + h.Value + "\",";
  }
  jwtHeader += "}";
  txtJwtOut.Text = "Header:\r\n" + JToken.Parse(jwtHeader).ToString(Formatting.Indented);

  //Extract the payload of the JWT
  var claims = token.Claims;
  var jwtPayload = "{";
  foreach(Claim c in claims)
  {
    jwtPayload += '"' + c.Type + "\":\"" + c.Value + "\",";
  }
  jwtPayload += "}";
  txtJwtOut.Text += "\r\nPayload:\r\n" + JToken.Parse(jwtPayload).ToString(Formatting.Indented);  
}

Я надеюсь, что ответить на ваши вопросы

...