如何在使用OpenIdConnect中间件时验证id_token中的声明?

时间:2018-01-13 13:08:09

标签: asp.net asp.net-core openid asp.net-core-2.0 gsuite

我在我的ASP.NET核心MVC应用中使用Oath2和Google身份验证。我想将登录用户限制为某个G Suite域,根据文档使用" hd" (托管域名)声明。我有它的工作,但它的身份验证和我不熟悉的想输入。我这样做了吗?有没有办法代替返回401状态代码而不是调用Fail()导致500错误?

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie()
        .AddOpenIdConnect(o =>
        {
            var hostedDomain = new KeyValuePair<string, string>("hd", "mysite.com");

            o.ClientId = "...";
            o.ClientSecret = "...";
            o.Authority = "https://accounts.google.com";
            o.ResponseType = "id_token token";
            o.Scope.Add("openid");
            o.Scope.Add("email");
            o.Scope.Add("profile");
            o.GetClaimsFromUserInfoEndpoint = true;
            o.SaveTokens = true;
            o.Events = new OpenIdConnectEvents()
            {
                OnRedirectToIdentityProvider = (context) =>
                {
                    // Add domain limiting using 'hd' or 'hosted domain' parameter
                    // Docs: https://developers.google.com/identity/protocols/OpenIDConnect#hd-param
                    //context.ProtocolMessage.SetParameter(hostedDomain.Key, "asdf.com");

                    // Set up redirect URLs
                    if (context.Request.Path != "/account/external")
                    {
                        context.Response.Redirect("/account/login");
                        context.HandleResponse();
                    }

                    return Task.FromResult(0);
                },

                OnTokenValidated = (c) =>
                {
                    var hdClaim = c.SecurityToken.Claims.FirstOrDefault(claim => claim.Type == hostedDomain.Key);
                    if(hdClaim?.Value == null || hdClaim.Value != hostedDomain.Value)
                    {
                        // The claim is null or value is not the trusted google domain - do not authenticate!
                        c.Fail($"Invalid claim for '{hostedDomain.Key}'!  User does not belong to trusted G Suite Domain");
                    }
                    return Task.FromResult(0);
                }


            };
        });

    services.AddMvc();
}

如果通过使用不在hostedDomain.Value中的域名中的帐户登录来执行不正确或无效的hd声明,则上述方法有效。我尝试设置c.Response.StatusCode = 401;,但用户仍然登录。

1 个答案:

答案 0 :(得分:0)

另一种方法是使用授权

您可以设置默认授权策略,该策略要求存在您要测试的声明。然后,任何没有声明的呼叫者将被重定向到拒绝访问的页面。类似的东西:

services.AddAuthorization(o =>
{
    o.AddPolicy("default", policy =>
    {
        policy.RequireAuthenticatedUser()
            .RequireClaim("hd", "mysite.com");
    });
});
services.AddMvc(o =>
{
    o.Filters.Add(new AuthorizeFilter("default"));
});