Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.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/2/.net/20.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# 不支持标识服务器响应类型:代码+;身份证_C#_.net_Owin_Identityserver4_Openid Connect - Fatal编程技术网

C# 不支持标识服务器响应类型:代码+;身份证

C# 不支持标识服务器响应类型:代码+;身份证,c#,.net,owin,identityserver4,openid-connect,C#,.net,Owin,Identityserver4,Openid Connect,我有一个identity server 4项目作为服务器,asp.net mvc 5作为客户端。除了一个偶然的问题外,一切正常:响应类型不受支持:代码+id\U令牌 在我从生产日志进行调查的过程中,我发现授权url偶尔被编码两次,然后我无法找到根本原因并复制。我猜这是Microsoft.Owin.Security.OpenIdConnect的内部行为 当未登录的用户访问受保护的资源时,将自动生成授权的url 从我的mvc客户端,首先将“代码id_令牌”编码为“代码+id_令牌”,然后将“代码+i

我有一个identity server 4项目作为服务器,asp.net mvc 5作为客户端。除了一个偶然的问题外,一切正常:响应类型不受支持:代码+id\U令牌

在我从生产日志进行调查的过程中,我发现授权url偶尔被编码两次,然后我无法找到根本原因并复制。我猜这是Microsoft.Owin.Security.OpenIdConnect的内部行为

当未登录的用户访问受保护的资源时,将自动生成授权的url

从我的mvc客户端,首先将“代码id_令牌”编码为“代码+id_令牌”,然后将“代码+id_令牌”编码为“代码%2Bid_令牌”

从我的身份服务器端,“代码%2Bid_令牌”被解码为“代码+id_令牌”,从而发生验证错误

以下是我的日志:

INFO  11:54:35 Request starting HTTP/1.1 GET http://login.example.com/connect/authorize?client_id=gjcf_mvc&nonce=636709820590066816.ZWNlNzJmOGQtMGFhNC00NzVkLTllNzktNmE5NTIzN2EzNDE3NThhMmI2OGYtODI5Mi00OTE2LTgzN2MtNGFkZWUzODQ4Nzlk&redirect_uri=https%3A%2F%2Fwww.example.com%2Fsignin-oidc&response_mode=form_post&response_type=code%2Bid_token&scope=openid%2Bprofile%2Bapi1%2BGjcfApi%2Boffline_access&state=OpenIdConnect.AuthenticationProperties 

INFO  11:54:35 Invoking IdentityServer endpoint: IdentityServer4.Endpoints.AuthorizeEndpoint for /connect/authorize

ERROR 11:54:35 Response type not supported: code+id_token
{
  "ClientId": "gjcf_mvc",
  "ClientName": "gjcf_mvc_name",
  "RedirectUri": "https://www.example.com/signin-oidc",
  "AllowedRedirectUris": [
    "https://www.example.com/signin-oidc"
  ],
  "SubjectId": "anonymous",
  "RequestedScopes": "",
  "State": "OpenIdConnect.AuthenticationProperties=5USuW-uf3wCad1ap9VCDDCE6bTKr1mUMZob-yI_vBUsAFqx_7oLv-0f3rTApD5_6NjVf3siQsJKg9cH4T7YA6ra2B_6_Yooq_S0rJW2L3I4a13Gg5DpcESjg8gb4MQSysOm_xLjgXa96gpGN0tTwNmnb6dB6S3c3ttIDPt_JWCI0qHclfprE_RlO4RlY3LqsI3YhGznHUXM9UW-x38KB9vUtdfulXYrWRko35cQmezI3QAIXqOCt_d7qLgL5WBeNRRk8I0QrbfrmhTwwtS1fTBi5vUPujBPi9L14mCeKPbNZIm5w4oqZOznjBhw0k5v2",
  "Raw": {
    "client_id": "gjcf_mvc",
    "nonce": "636709820590066816.ZWNlNzJmOGQtMGFhNC00NzVkLTllNzktNmE5NTIzN2EzNDE3NThhMmI2OGYtODI5Mi00OTE2LTgzN2MtNGFkZWUzODQ4Nzlk",
    "redirect_uri": "https://www.example.com/signin-oidc",
    "response_mode": "form_post",
    "response_type": "code+id_token",
    "scope": "openid+profile+api1+GjcfApi+offline_access",
    "state": "OpenIdConnect.AuthenticationProperties"
  }
}
以下代码位于asp.net mvc启动中:

app.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    AuthenticationType = "Cookies",
                    Provider = new CookieAuthenticationProvider
                    {
                        OnResponseSignIn = context =>
                        {
                            context.Properties.AllowRefresh = true;
                            context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(40);
                        }
                    }
                });

                GjcfOpenIdConnectConfiguration conf = GjcfOpenIdConnectConfiguration.Instance;

                app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
                {
                    ClientId = conf.ClientId,
                    ClientSecret = conf.ClientSecret,
                    Authority = conf.Authority,
                    RedirectUri = conf.RedirectUri,
                    PostLogoutRedirectUri = conf.PostLogoutRedirectUri,

                    ResponseType = conf.ResponseType,
                    Scope = conf.Scope,
                    SignInAsAuthenticationType = "Cookies",


                    Notifications = new OpenIdConnectAuthenticationNotifications
                    {
                        AuthorizationCodeReceived = async n =>
                        {
                            // use the code to get the access and refresh token
                            var tokenClient = new TokenClient(
                                conf.TokenAddress,
                                conf.ClientId,
                                conf.ClientSecret);

                            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(
                                new Uri(conf.UserInfoAddress),
                                tokenResponse.AccessToken);

                            var userInfoResponse = await userInfoClient.GetAsync();

                            // create new identity
                            var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
                            id.AddClaims(userInfoResponse.GetClaimsIdentity().Claims);

                            id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
                            id.AddClaim(new Claim("expires_at",
                                DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime().ToString()));
                            id.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken));
                            id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
                            id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value));
                            id.AddClaim(new Claim(ClaimTypes.NameIdentifier,
                                n.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value));
                            id.AddClaim(new Claim(
                                "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
                                n.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value));

                            n.AuthenticationTicket = new AuthenticationTicket(
                                new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType,
                                    "name", "role"),
                                n.AuthenticationTicket.Properties);
                        },

                        AuthenticationFailed = (context) =>
                        {
                            if (context.Exception.Message.StartsWith("OICE_20004") || context.Exception.Message.Contains("IDX10311"))
                            {
                                context.SkipToNextMiddleware();
                                return Task.FromResult(0);
                            }
                            return Task.FromResult(0);
                        },

                        RedirectToIdentityProvider = n =>
                        {                                    
                            // if signing out, add the id_token_hint
                            if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                            {
                                var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

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

                            }

                            return Task.FromResult(0);
                        }
                    }
                });
当用户访问标记为Authorize属性的操作时,将生成Authorize url

[Authorize]
        public ActionResult IdentityServerJump(string returnUrl)
        {
            if (!string.IsNullOrEmpty(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }

虽然您还没有提供代码,但以下部分存在问题

从我的mvc客户端,“代码id_令牌”首先编码为“代码+id_令牌”,然后将“代码+id_令牌”编码为“代码%2Bid_令牌”

不知道为什么要进行双重编码。从IS4(identity server)端,它将执行URL解码,而不知道查询段是双重编码的

对此的更正是使用单一编码。根据OpenID连接规范,坚持使用
%20对空格进行编码,不要像现在这样进行双重编码。!!。另外,我也欢迎您阅读关于+vs%20的文章,请您提供一些相关代码。欢迎访问SO,您在提出第一个问题方面做得很好。正如@Dimitar提到的,一个代码将有助于识别您正在经历的双重编码。@Michael Zhang您找到解决方案了吗?我也有同样的问题。我认为这是基于用户使用的浏览器。但是我不知道如何修复它。谢谢,我在编码方面什么都不做,url是由oidc中间件生成和编码的,我每天只看到一两个错误log@MichaelZhang示例代码将非常有用:)