[英]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 的新手,我试图了解以下内容:
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验证/
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 上配置的重定向控制器/操作(页面)?
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?
有没有办法扩展这个?
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.