身份服务器客户端的 AccessToken 为空
AccessToken is null for identity server client
我有以下 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,
and ResponseType = "code id_token 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));
结果令牌只有一个范围(即测试范围),而不是为该客户端定义的所有其他范围。
它为空,因为您没有请求访问令牌。
ResponseType = "code id_token"
表示在回调上给客户端一个 "Authoriziation Code" 和一个 "Id token" 。要接收访问令牌,
- 将
token
包含在 ResponseType
中作为 ResponseType = "code id_token token"
并将客户端流更新为混合流(代码 + 令牌),因为这就是我们现在正在做的。
或
- 使用
ProtocolMessage
上可用的 "Authorization Code" 使用 /token
端点获取访问令牌。
访问令牌不应与代码和 id_token 一起返回。
获取它的正确方法是使用客户端 ID 和客户端密码通过后台通道。
将此添加到通知块:
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
}
}
我有以下 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,
and ResponseType = "code id_token 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));
结果令牌只有一个范围(即测试范围),而不是为该客户端定义的所有其他范围。
它为空,因为您没有请求访问令牌。
ResponseType = "code id_token"
表示在回调上给客户端一个 "Authoriziation Code" 和一个 "Id token" 。要接收访问令牌,
- 将
token
包含在ResponseType
中作为ResponseType = "code id_token token"
并将客户端流更新为混合流(代码 + 令牌),因为这就是我们现在正在做的。
或
- 使用
ProtocolMessage
上可用的 "Authorization Code" 使用/token
端点获取访问令牌。
访问令牌不应与代码和 id_token 一起返回。 获取它的正确方法是使用客户端 ID 和客户端密码通过后台通道。 将此添加到通知块:
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
}
}