IIS / ASP.NET-如何提供ClaimsPrincipal?

时间:2019-06-25 19:45:34

标签: asp.net iis

我想要一个(.NET Core)Web API网站。在请求进入我的站点之前,它必须通过辅助站点(“网关”)。网关将找出声明并使用自定义声明创建一个IClaimsPrinciple。就我而言,网关可以通过魔术设置这些主张。我的api将信任他们100%。

然后,网关将向我的api发出自己的请求,以某种方式附加声明信息。当请求到达我的api网站时,声明已被设置

网关站点如何将声明“附加”到http请求?

一个类似的用例是,如果IIS设置为Windows auth。当我在(不受保护的)控制器方法中检查静态User对象时,可以看到它是WindowsPrincipal,它的声明类似于AD用户组。 (据我所知)我的代码对添加这些声明的请求没有任何作用;似乎IIS更改了将这些声明附加到我的网站之前的请求。

我要问的可能吗?如果是这样,您如何根据请求设置原则?还是我完全误解了如何设定原则?在Windows Auth示例中,.NET项目中是否设置了WindowsPrinciple?

1 个答案:

答案 0 :(得分:1)

您是否在问:“如何在对用户进行身份验证之后但在用户尝试使用受保护的资源之前,如何从可执行文件内部向用户添加自定义声明”?

“受保护的资源”是指受[Authorize]属性保护的任何内容。

如果您要问的是,我没有.Net Core示例,但是我有.Net Framework示例,将其转换为.Net Core可能很容易。

是的,它是在中间件的Startup类的Configuration方法中完成的。在下面的示例中,我使用Auth0进行身份验证。下面是整个方法,但向下滚动到“ SecurityTokenValidated”以查看向身份添加声明的示例。在实际的应用程序中,您可能会从身份中提取一些唯一的密钥,然后在数据库中查找声明。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // Configure Auth0 parameters
        string auth0Domain = ConfigurationManager.AppSettings["auth0:Domain"];
        string auth0ClientId = ConfigurationManager.AppSettings["auth0:ClientId"];
        string auth0ClientSecret = ConfigurationManager.AppSettings["auth0:ClientSecret"];
        string auth0RedirectUri = ConfigurationManager.AppSettings["auth0:RedirectUri"];
        string auth0PostLogoutRedirectUri = ConfigurationManager.AppSettings["auth0:PostLogoutRedirectUri"];

        // Enable Kentor Cookie Saver middleware
        app.UseKentorOwinCookieSaver();

        // Set Cookies as default authentication type
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
            LoginPath = new PathString("/Account/Login")
        });

        // Configure Auth0 authentication
        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            AuthenticationType = "Auth0",

            Authority = $"https://{auth0Domain}",

            ClientId = auth0ClientId,
            ClientSecret = auth0ClientSecret,

            RedirectUri = auth0RedirectUri,
            PostLogoutRedirectUri = auth0PostLogoutRedirectUri,

            ResponseType = OpenIdConnectResponseType.CodeIdToken,
            Scope = "openid profile",

            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name",
                RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
            },

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                RedirectToIdentityProvider = notification =>
                {
                    if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                    {
                        var logoutUri = $"https://{auth0Domain}/v2/logout?client_id={auth0ClientId}";

                        var postLogoutUri = notification.ProtocolMessage.PostLogoutRedirectUri;
                        if (!string.IsNullOrEmpty(postLogoutUri))
                        {
                            if (postLogoutUri.StartsWith("/"))
                            {
                                // transform to absolute
                                var request = notification.Request;
                                postLogoutUri = request.Scheme + "://" + request.Host + request.PathBase + postLogoutUri;
                            }
                            logoutUri += $"&returnTo={ Uri.EscapeDataString(postLogoutUri)}";
                        }

                        notification.Response.Redirect(logoutUri);
                        notification.HandleResponse();
                    }
                    return Task.FromResult(0);
                },
                //this fires when a user is redirected to Auth0 for authentication.
                SecurityTokenValidated = (context) =>
                {
                    var identity = context.AuthenticationTicket.Identity;
                    var uniqueKey = identity.FindFirst("MyUniqueKey");
                    //lookup something in database using unique key
                    identity.AddClaim(new System.Security.Claims.Claim(ClaimTypes.Role, "SomeRole"));
                    return Task.FromResult(0);
                }
            }
        });
    }
}

}