身份服务器客户端的AccessToken为null

时间:2016-11-27 15:40:04

标签: identityserver3 identityserver4

我有以下openid选项:

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



            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                AuthenticationType = "oidc",
                SignInAsAuthenticationType = "Cookies",
                Authority = "http://localhost:5000",              
                ClientId = "mvcClient",
                ClientSecret = "secret",
                RedirectUri = "http://localhost:5002/signin-oidc",
                PostLogoutRedirectUri = "http://localhost:5002",
                ResponseType = "code id_token",                            
                Scope = "openid profile",

                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    SecurityTokenValidated = async n =>
                    {
                        var claims_to_exclude = new[]
                        {
                            "aud", "iss", "nbf", "exp", "nonce", "iat", "at_hash"
                        };

                        var claims_to_keep =
                            n.AuthenticationTicket.Identity.Claims
                            .Where(x => false == claims_to_exclude.Contains(x.Type)).ToList();
                        claims_to_keep.Add(new Claim("id_token", n.ProtocolMessage.IdToken));




                        if (n.ProtocolMessage.AccessToken != null)
                        {
                            claims_to_keep.Add(new Claim("access_token", n.ProtocolMessage.AccessToken));

   }    
  }    
 }
}

我看到n.ProtocolMessage.AccessToken总是为空。

我在身份服务器中配置了客户端,如下所示:

 new Client()
                {
                    ClientId = "mvcClient",
                    ClientName = "MVC Client",                      
                    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

                    ClientSecrets = new List<Secret>()
                    {
                        new Secret("secret".Sha256())
                    },

                   // RequireConsent = false,

                    // where to redirect to after login
                    RedirectUris = { "http://localhost:5002/signin-oidc" },
                    // where to redirect to after logout
                    PostLogoutRedirectUris = { "http://localhost:5002" },

                    AllowedScopes =
                    {
                        StandardScopes.OpenId.Name,
                        StandardScopes.Profile.Name,
                        StandardScopes.OfflineAccess.Name,
                        StandardScopes.Roles.Name,
                        "API"
                    }
                },

我想知道为什么n.ProtocolMessage.AccessToken为null,我怎样才能得到它的值

更新

如果我将客户类型更改为混合,请执行以下操作:

AllowedGrantTypes = GrantTypes.Hybrid,

和ResponseType =&#34;代码id_token令牌:

我在服务器上出现invalid_request错误

如果我尝试获取此类访问令牌(在通知中):

var client = new TokenClient("http://localhost:5000/connect/token", "mvcClient", "secret");
                            var response = client.RequestClientCredentialsAsync("testscope").Result;
                            var accesstoken = response.AccessToken;
                            claims_to_keep.Add(new Claim("access_token", accesstoken));

结果标记只有一个范围(即testscope),而不是为该客户端定义的所有其他范围。

2 个答案:

答案 0 :(得分:1)

它因为您没有要求访问令牌而为空。

ResponseType = "code id_token"表示向客户提供&#34;授权代码&#34;和一个&#34; Id令牌&#34;在回调上。要接收访问令牌,

  1. token中加ResponseType作为ResponseType = "code id_token token"&amp;将客户端流程更新为混合流程(代码+令牌),因为这是我们现在正在做的事情。
    1. 使用&#34;授权码&#34;使用/token端点获取访问令牌可在ProtocolMessage上找到。

答案 1 :(得分:0)

访问令牌不应与代码和id_token一起带回。 正确的方法是通过使用客户ID和客户机密的反向渠道。 将此添加到Notifications块:

AuthorizationCodeReceived = async n =>
{
    var tokenClient = new TokenClient(n.Options.Authority + "/connect/token", "Client_Id", "secret");
    var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri);

    if (tokenResponse.IsError)
    {
        throw new Exception(tokenResponse.Error);
    }
    else
    {
        string accessToken = tokenResponse.AccessToken;
        //Other logic
    }
}