Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在OWIN中间件中将自定义头添加到开放id连接身份验证请求_C#_Asp.net Mvc_Oauth_Openid_Identityserver3 - Fatal编程技术网

C# 如何在OWIN中间件中将自定义头添加到开放id连接身份验证请求

C# 如何在OWIN中间件中将自定义头添加到开放id连接身份验证请求,c#,asp.net-mvc,oauth,openid,identityserver3,C#,Asp.net Mvc,Oauth,Openid,Identityserver3,我有一个系统,其中有一个调用web api的MVC网站。我已使用OAUTH和OPENID Connect进行身份验证/授权。我使用Thinktecture的IdentityServer 3在另一个web api项目中设置了一个identity server。在MVC项目中,我在OWIN启动类中重定向到identity server。这些都是相当标准的东西,而且运行良好 我现在被要求将web api和identity server置于Azure api管理之后。这也很好,因为我在MVC项目中需要做

我有一个系统,其中有一个调用web api的MVC网站。我已使用OAUTH和OPENID Connect进行身份验证/授权。我使用Thinktecture的IdentityServer 3在另一个web api项目中设置了一个identity server。在MVC项目中,我在OWIN启动类中重定向到identity server。这些都是相当标准的东西,而且运行良好

我现在被要求将web api和identity server置于Azure api管理之后。这也很好,因为我在MVC项目中需要做的就是将API管理中的订阅密钥作为头(“Ocp Apim订阅密钥”)添加到web API的任何请求中。到目前为止还不错

问题是我现在需要将这个头添加到任何对identity server的请求中,除了编写自己的中间件之外,我无法解决如何添加头的问题。我的Startup类如下所示:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(IocHelper.GetContainer()));

        JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies"
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            ClientId = ConfigurationHelper.GetClientId(),
            Authority = ConfigurationHelper.GetSecurityTokenServiceUrl(),
            RedirectUri = ConfigurationHelper.GetPortalHomePageUrl(),
            PostLogoutRedirectUri = ConfigurationHelper.GetPortalHomePageUrl(),
            ResponseType = "code id_token",
            Scope = "openid profile public_api",
            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name",
                RoleClaimType = "role"
            },

            SignInAsAuthenticationType = "Cookies",


            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthorizationCodeReceived = async n =>
                {
                    // use the code to get the access and refresh token
                    var tokenClient = new TokenClient(ConfigurationHelper.GetTokenEndpointUrl(), ConfigurationHelper.GetClientId(), ConfigurationHelper.GetClientSecret());
                    var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri);
                    if (tokenResponse.IsError)
                    {
                        throw new Exception(tokenResponse.Error);
                    }

                    // use the access token to retrieve claims from userinfo
                    var userInfoClient = new UserInfoClient(ConfigurationHelper.GetUserInfoUrl());
                    var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);
                    if (userInfoResponse.IsError)
                    {
                        throw new Exception(userInfoResponse.Error);
                    }

                    // create new identity
                    var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
                    foreach (var c in userInfoResponse.Claims)
                    {
                        id.AddClaim(new Claim(c.Type, c.Value));
                    }

                    id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
                    id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(tokenResponse.ExpiresIn * 2).ToLocalTime().ToString(CultureInfo.InvariantCulture)));
                    id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
                    id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value));


                    var claimsIdentity = new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role");
                    //claimsIdentity.IsAuthenticated = true;
                    n.AuthenticationTicket = new AuthenticationTicket(claimsIdentity, n.AuthenticationTicket.Properties);
                },
                RedirectToIdentityProvider = n =>
                {
                    // if signing out, add the id_token_hint
                    if (n.ProtocolMessage.RequestType != OpenIdConnectRequestType.LogoutRequest)
                    {
                        return Task.FromResult(0);
                    }

                    var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

                    if (idTokenHint != null)
                    {
                        n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                    }

                    // DOESN'T WORK
                    n.OwinContext.Request.Headers.Append("Ocp-Apim-Subscription-Key", "MY KEY GOES HERE");

                    // ALSO DOESN'T WORK
                    n.Request.Headers.Append("Ocp-Apim-Subscription-Key", "MY KEY GOES HERE");

                    return Task.FromResult(0);
                }
            }
        });
    }
}
公共类启动
{
公共无效配置(IAppBuilder应用程序)
{
SetResolver(新的SimpleInjectorDependencyResolver(IocHelper.GetContainer());
JwtSecurityTokenHandler.InboundClaimTypeMap=new Dictionary();
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(新的CookieAuthenticationOptions
{
AuthenticationType=“Cookies”
});
app.UseOpenIdConnectAuthentication(新的OpenIdConnectAuthenticationOptions
{
ClientId=ConfigurationHelper.GetClientId(),
Authority=ConfigurationHelper.GetSecurityTokenServiceUrl(),
RedirectUri=ConfigurationHelper.GetPortalHomePageUrl(),
PostLogoutRedirectUri=ConfigurationHelper.GetPortalHomePageUrl(),
ResponseType=“代码id\u令牌”,
Scope=“openid profile public\u api”,
TokenValidationParameters=新的TokenValidationParameters
{
NameClaimType=“name”,
RoleClaimType=“角色”
},
SignInAsAuthenticationType=“Cookies”,
通知=新的OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived=异步n=>
{
//使用代码获取访问和刷新令牌
var tokenClient=new tokenClient(ConfigurationHelper.GetTokenEndpointUrl()、ConfigurationHelper.GetClientId()、ConfigurationHelper.GetClientSecret());
var tokenResponse=wait tokenClient.RequestAuthorizationCodeAsync(n.Code,n.RedirectUri);
if(tokenResponse.IsError)
{
抛出新异常(tokenResponse.Error);
}
//使用访问令牌从userinfo检索声明
var userInfoClient=newuserinfoclient(ConfigurationHelper.GetUserInfoUrl());
var userInfoResponse=await userInfoClient.GetAsync(tokenResponse.AccessToken);
if(userInfoResponse.IsError)
{
抛出新异常(userInfoResponse.Error);
}
//创建新身份
var id=新的ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
foreach(userInfoResponse.Claims中的var c)
{
id.AddClaim(新索赔(c.Type,c.Value));
}
id.AddClaim(新的声明(“access_token”,tokenResponse.AccessToken));
id.AddClaim(新声明(“expires_at”,DateTime.Now.AddSeconds(tokenResponse.ExpiresIn*2).ToLocalTime().ToString(CultureInfo.InvariantCulture));
id.AddClaim(新声明(“id_token”,n.ProtocolMessage.IdToken));
id.AddClaim(新声明(“sid”,n.AuthenticationTicket.Identity.FindFirst(“sid”).Value));
var claimsIdentity=new claimsIdentity(id.Claims,n.AuthenticationTicket.Identity.AuthenticationType,“名称”,“角色”);
//claimsIdentity.IsAuthenticated=true;
n、 AuthenticationTicket=新的AuthenticationTicket(claimsIdentity,n.AuthenticationTicket.Properties);
},
RedirectToIdentityProvider=n=>
{
//如果注销,请添加id\u令牌\u提示
if(n.ProtocolMessage.RequestType!=OpenIdConnectRequestType.LogoutRequest)
{
返回Task.FromResult(0);
}
var idTokenHint=n.OwinContext.Authentication.User.FindFirst(“id_令牌”);
if(idTokenHint!=null)
{
n、 ProtocolMessage.IdTokenHint=IdTokenHint.Value;
}
//不起作用
n、 OwinContext.Request.Headers.Append(“Ocp Apim订阅密钥”,“我的密钥在这里”);
//也不起作用
n、 Append(“Ocp Apim订阅密钥”,“我的密钥在这里”);
返回Task.FromResult(0);
}
}
});
}
}

有没有办法将请求高速插入identity server并在其中添加我自己的头?

在发送请求之前会调用一个通知,名为
RedirectToIdentity Provider
,您可能可以在其中找到帮助您的内容。从我上次查看中间件的源代码来看,
ProtocolMessage
可能是您想要覆盖某些内容的地方。我删除了我的答案,因为它不起作用,但这是OP在那里的最后一条评论,解释了他在
方面的工作。再次感谢。最后,我将Identity server端点设置为API管理,使其不需要订阅,这意味着我不需要订阅