简体   繁体   English

如何验证asp.net mvc OWIN从azure AD B2C收到的id_token

[英]How to validate id_token received by asp.net mvc OWIN from azure AD B2C

We have a security requirement that we must validate the id token we receive from Azure AD B2C.我们有一个安全要求,即必须验证从 Azure AD B2C 收到的 id 令牌。 We need to validate these at the minimum我们至少需要验证这些

customSecurityLevel , audience , not before and "expiration time", issuer, nonce customSecurityLevel ,观众, not before 和 "expiration time", issuer, nonce

Looking asp.net MVC OWIN middleware, I noticed that that OpenIdConnectAuthenicationOptions provides these:查看asp.net MVC OWIN中间件,我注意到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
                },
            };

Being quiet new to OWIN, I'm trying to understand below:作为 OWIN 的新手,我试图了解以下内容:

  1. Does OWIN middleware magically validates the token we receive from Azure AD B2C or do we need to manually perform validation per this: https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-webapi-manual-jwt-validation/ OWIN 中间件是否神奇地验证了我们从 Azure AD B2C 收到的令牌,或者我们是否需要手动执行验证: https : //azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-webapi-手动jwt验证/

  2. At what point in time should token validation should occur ie AuthorizationCodeReceived event or on redirect controller/action (page) that's configured on Azure AD B2C redirect URL?应在什么时间点进行令牌验证,即 AuthorizationCodeReceived 事件或在 Azure AD B2C 重定向 URL 上配置的重定向控制器/操作(页面)?

  3. We need to validate more attributes that TokenValidationParameters supports eg customSecurityAttribute we send on initial payload.我们需要验证 TokenValidationParameters 支持的更多属性,例如我们在初始负载上发送的 customSecurityAttribute。 Is there a way to extend this?有没有办法扩展这个?

    1. How do we parse the token that we receive from Azure AD B2C using OWIN?我们如何使用 OWIN 解析从 Azure AD B2C 收到的令牌?

Any code sample would be handy.任何代码示例都会很方便。

TO make your question simpler.让你的问题更简单。

The idea behind token is to parse the token and get 3 parts from the token token 背后的想法是解析 token 并从 token 中获取 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).

Next step the user sends request to your back-end along with JWT.下一步,用户将请求与 JWT 一起发送到您的后端。

your back-end will parse the token and get certificate type then will preform HTTP request to your identity provider to get certificate您的后端将解析令牌并获取证书类型,然后向您的身份提供者执行 HTTP 请求以获取证书

Next your back-end will construct the certificate option and try to do encryption for ( header + Payload) came from your token the output string must be exactly same Signature you received in the token from your front-end.接下来,您的后端将构建证书选项,并尝试对来自您的令牌的(标头 + 有效负载)进行加密,输出字符串必须与您在前端的令牌中收到的签名完全相同。

If every thing is okay now your back-end will start validating other attributes like Audience, Issuer if you configure your token to validate the Audience means your front-end required to provide token contain Audience(Application ID) exactly same your back-end as well as for issuer.如果现在一切正常,您的后端将开始验证其他属性,例如 Audience、Issuer,如果您配置令牌以验证 Audience,则意味着您需要提供的前端需要提供的令牌包含与后端完全相同的 Audience(Application ID)以及对于发行人。

the question now how my back-end knows about certificate?现在的问题是我的后端如何知道证书? Azure AD using OpenID connect, More information here since you configred you tenant in backend the auth packge will make a call to https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration to get the details about your identity provider and one important link as will is ("jwks_uri": "https://login.microsoftonline.com/common/discovery/keys") where the signature hosted. Azure AD 使用 OpenID 连接, 这里有更多信息,因为您在后端配置了租户,身份验证包将调用https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration以获取详细信息关于您的身份提供者和签名托管的一个重要链接("jwks_uri": "https://login.microsoftonline.com/common/discovery/keys") You can read and search more how to validate certificate JWT and check this https://codereview.stackexchange.com/questions/70005/authentication-with-jwt您可以阅读和搜索更多如何验证证书 JWT 并检查此https://codereview.stackexchange.com/questions/70005/authentication-with-jwt

moving to part 2 of validate more attributes.转到验证更多属性的第 2 部分。 Since you are using OpenIdConnect, the package has class called OpenIdConnectEvents that you can trigger events and do what ever you want like this由于您使用的是 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);
                }
            }
        };
});

moving to part 3 parsing token in javascript转到第 3 部分在 javascript 中解析令牌

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

parsing token in C#在 C# 中解析令牌

use this libary https://www.jsonwebtoken.io/使用这个库https://www.jsonwebtoken.io/

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

or manual或手册

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);  
}

I hope that answer your qustions我希望能回答你的问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Azure AD B2C - 如何为id_token交换用户名/密码? - Azure AD B2C - how is username/password exchanged for id_token? Azure B2C 拒绝=“?” 在 ASP.NET MVC 中 - Azure B2C deny="?" in asp.net MVC 如何从 Azure AD B2C 用户商店获取 ASP.NET Core 3.1 中的用户信息? - How to get user information in ASP.NET Core 3.1 from Azure AD B2C user store? ASP.NET Core 3.1 如何使用 Azure AD B2C 返回 401 Unauthorized 而不是 Challenge - ASP.NET Core 3.1 how to return 401 Unauthorized instead of Challenge with Azure AD B2C 如何在 ASP.NET MVC 中获取/设置自定义 Azure Active Directory B2C 用户属性? - How to get/set custom Azure Active Directory B2C user attributes in ASP.NET MVC? 如何使用 C# 和 .net 验证 MS Azure AD 生成的 JWT id_token? - How to verify JWT id_token produced by MS Azure AD with C# and .net? 无法使用来自我的 asp.net 核心 web 应用程序的 AAD B2C 中的自定义策略登录多租户 Azure AD - unable to sign In for MultiTenant Azure AD using Custom policies in AAD B2C from my asp.net core web app Azure B2C 检查用户 email Id 是否存在或不使用 ASP.NET Core 3.1 MVC 中的图表 - Azure B2C check user email Id exists or not using Graph in ASP.NET Core 3.1 MVC 使用ASP.NET Core的Azure AD B2C - 无法编辑配置文件 - Azure AD B2C with ASP.NET Core - Unable to go to edit profile ASP.NET 浏览器关闭后核心身份验证未保持登录状态(Azure AD B2C) - ASP.NET Core Auth not staying signed in after browser closes (Azure AD B2C)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM