identityserver4 with redux -oidc client requested access token - 但客户端未配置为通过浏览器接收访问令牌
identityserver4 with redux -oidc client requested access token - but client is not configured to receive access tokens via browser
我的 identityserver4 客户端如下所示:
new Client {
ClientId = "openIdConnectClient",
ClientName = "Example Implicit Client Application",
//AllowedGrantTypes = GrantTypes.Implicit,
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowOfflineAccess = true,
AllowAccessTokensViaBrowser = true,
AccessTokenLifetime = 30,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"role",
"customAPI.write"
},
RedirectUris = new List<string> {"http://localhost:8080/callback"},
PostLogoutRedirectUris = new List<string> {"https://localhost:44330"},
AllowedCorsOrigins = new List<string>
{
"http://127.0.0.1:8080",
"http://localhost:8080",
"*"
},
}
在 React 应用程序中,我的 userManager class 看起来像这样:
import { createUserManager } from 'redux-oidc';
const userManagerConfig = {
client_id: 'openIdConnectClient',
redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}/callback`,
//response_type: 'code id_token token',
response_type: 'token id_token',
scope: 'openid profile email role',
authority: 'http://localhost:50604',
silent_redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}/silent_renew.html`,
automaticSilentRenew: true,
filterProtocolClaims: true,
loadUserInfo: true,
};
const userManager = createUserManager(userManagerConfig);
export default userManager;
问题是:当我尝试从 redux-oidc 示例应用程序调用我的 identityserver4 时。我收到以下错误:
Client requested access token - but client is not configured to receive access tokens via browser
希望你能理解我的问题。请有人帮我解决这个问题。我已经为下面的示例应用程序提供了 link。
您的代码包含两种不同的授权类型。 Identity server 4 中不同的 Grant types 有不同的要求。这里有一些信息可以帮助您了解您正在使用的不同类型。它还可以帮助您了解您遇到此问题的原因。
GrantTypes.ClientCredentials
客户端凭据是最简单的授权类型,用于服务器到服务器的通信 - 始终代表客户端而不是用户请求令牌。
使用此授权类型,您可以向令牌端点发送令牌请求,并取回代表客户端的访问令牌。客户端通常必须使用其客户端 ID 和密码通过令牌端点进行身份验证。
new Client
{
ClientId = "client",
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ClientCredentials,
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
// scopes that client has access to
AllowedScopes = { "api1" }
}
GrantTypes.Implicit
隐式授权类型针对基于浏览器的应用程序进行了优化。仅用于用户身份验证(服务器端和 JavaScript 应用程序),或身份验证和访问令牌请求(JavaScript 应用程序)。
在隐式流程中,所有令牌都通过浏览器传输,因此不允许使用刷新令牌等高级功能。如果您想通过浏览器通道传输访问令牌,您还需要在客户端配置中明确允许:
Client.AllowAccessTokensViaBrowser = true;
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.Implicit,
// where to redirect to after login
RedirectUris = { "http://localhost:5002/signin-oidc" },
// where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
},
AllowAccessTokensViaBrowser = true
}
我的 identityserver4 客户端如下所示:
new Client {
ClientId = "openIdConnectClient",
ClientName = "Example Implicit Client Application",
//AllowedGrantTypes = GrantTypes.Implicit,
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowOfflineAccess = true,
AllowAccessTokensViaBrowser = true,
AccessTokenLifetime = 30,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"role",
"customAPI.write"
},
RedirectUris = new List<string> {"http://localhost:8080/callback"},
PostLogoutRedirectUris = new List<string> {"https://localhost:44330"},
AllowedCorsOrigins = new List<string>
{
"http://127.0.0.1:8080",
"http://localhost:8080",
"*"
},
}
在 React 应用程序中,我的 userManager class 看起来像这样:
import { createUserManager } from 'redux-oidc';
const userManagerConfig = {
client_id: 'openIdConnectClient',
redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}/callback`,
//response_type: 'code id_token token',
response_type: 'token id_token',
scope: 'openid profile email role',
authority: 'http://localhost:50604',
silent_redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}/silent_renew.html`,
automaticSilentRenew: true,
filterProtocolClaims: true,
loadUserInfo: true,
};
const userManager = createUserManager(userManagerConfig);
export default userManager;
问题是:当我尝试从 redux-oidc 示例应用程序调用我的 identityserver4 时。我收到以下错误:
Client requested access token - but client is not configured to receive access tokens via browser
希望你能理解我的问题。请有人帮我解决这个问题。我已经为下面的示例应用程序提供了 link。
您的代码包含两种不同的授权类型。 Identity server 4 中不同的 Grant types 有不同的要求。这里有一些信息可以帮助您了解您正在使用的不同类型。它还可以帮助您了解您遇到此问题的原因。
GrantTypes.ClientCredentials
客户端凭据是最简单的授权类型,用于服务器到服务器的通信 - 始终代表客户端而不是用户请求令牌。
使用此授权类型,您可以向令牌端点发送令牌请求,并取回代表客户端的访问令牌。客户端通常必须使用其客户端 ID 和密码通过令牌端点进行身份验证。
new Client
{
ClientId = "client",
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ClientCredentials,
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
// scopes that client has access to
AllowedScopes = { "api1" }
}
GrantTypes.Implicit
隐式授权类型针对基于浏览器的应用程序进行了优化。仅用于用户身份验证(服务器端和 JavaScript 应用程序),或身份验证和访问令牌请求(JavaScript 应用程序)。
在隐式流程中,所有令牌都通过浏览器传输,因此不允许使用刷新令牌等高级功能。如果您想通过浏览器通道传输访问令牌,您还需要在客户端配置中明确允许:
Client.AllowAccessTokensViaBrowser = true;
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.Implicit,
// where to redirect to after login
RedirectUris = { "http://localhost:5002/signin-oidc" },
// where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
},
AllowAccessTokensViaBrowser = true
}