我是Identity Server的新手。我之前没有配置它。但是我需要它来处理我正在进行的项目。
API将为Angular JS Client,iOS App和Android App提供服务。我们需要实现身份验证和授权。
注意:我正在尝试在同一个Web API项目中配置Identity Server和我的API。
我已按照文档操作并将Identity Server配置为以下内容:
在startup.cs中,ConfigureServices()
services.AddTransient<IProfileService, CustomProfileService>();
services.AddTransient<IResourceOwnerPasswordValidator, CustomResourceOwnerPasswordValidator>();
services.AddIdentityServer()
.AddTemporarySigningCredential()
// add the resources that need to be secured
.AddInMemoryApiResources(IdentityServerConfig.Resources.GetApiResources())
// add the clients that will be access the ApiResources
.AddInMemoryClients(IdentityServerConfig.Clients.GetClients());
CustomProfileService
和CustomResourceOwnerPasswordValidator
与此答案相同:https://stackoverflow.com/a/35306021/1910735
在Configure()
// as this API will also be acting as an
app.UseIdentityServer();
// now setup the Identity Server client, this API will also be the client
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "http://localhost:44337",
RequireHttpsMetadata = false,
ApiName = "obApi"
});
以下是GetClients()
public static IEnumerable<Client> GetClients()
{
var clients = new List<Client>();
var websiteGrants = new List<string> { GrantType.ResourceOwnerPassword };
var secret = new Secret("secret".Sha256());
var websiteClient = new Client()
{
// we will be using Angular JS to access the API - so naming it js
ClientId = "js",
// just a human friendly name
ClientName = "JavaScript Client",
// set to GrantType.ResourceOwnerPassword - because using Username/Password to login
AllowedGrantTypes = websiteGrants,
// secret for authentication
//TODO: Change the secret
ClientSecrets = { secret },
// we need to access the fhApi from Angular JS front-end
// fhApi is defined in Resources file as an API Resource
AllowedScopes = { "obApi" }
};
clients.Add(websiteClient);
return clients;
}
这是GetApiResources()
public static IEnumerable<ApiResource> GetApiResources()
{
// e.g. if we want to protect an API called api1 - then we will add it here
// these values are hard coded for now - but we can get from DB, config file etc.
return new List<ApiResource>
{
new ApiResource("obApi", "Order2Bite API")
};
}
现在因为我想使用Angular JS,iOS和Android我想从Identity Server获取Access Token,然后使用Access Token进行身份验证和授权。
为此我试图从JS客户端访问/connect/token
但我收到invalid_client
错误。
var user = { client_id: "js", grant_type: 'password', username: "testuser", password: "testpasswrd", scope: 'obApi' };
var urlEncodedUrl = {
'Content-Type': 'application/x-www-form-urlencoded',
};
this.$http({
method: 'POST', url: "http://localhost:44337/connect/token",
headers: urlEncodedUrl,
data: user,
})
.then(data => {
console.log(data)
},
data => {
console.log(data)
});
我在服务器端遇到的错误是&#39;找不到客户标识符&#39;:
1 - 为什么我收到此错误?
2 - 由于我需要在JS,Android和iOS中以编程方式获取令牌,我需要使用/connect/token
,我对此是否正确?我正走在正确的道路上吗?
答案 0 :(得分:2)
invalid_client错误通常表示客户端ID或客户端密钥不正确。在这种情况下,您不会在对IdentityServer的请求中包含客户端密钥。添加&#34; client_secret:&#39; secret&#39;&#34;根据您的要求
更新数据:
var user = { client_id: "js", client_secret: "secret", grant_type: 'password', username: "testuser", password: "testpasswrd", scope: 'obApi' };
或者,您不能在客户端配置中要求ClientSecret
var websiteClient = new Client()
{
// we will be using Angular JS to access the API - so naming it js
ClientId = "js",
// just a human friendly name
ClientName = "JavaScript Client",
// set to GrantType.ResourceOwnerPassword - because using Username/Password to login
AllowedGrantTypes = websiteGrants,
// secret for authentication
//TODO: Change the secret
ClientSecrets = { secret },
// Disable client secret validation
RequireClientSecret = false,
// we need to access the fhApi from Angular JS front-end
// fhApi is defined in Resources file as an API Resource
AllowedScopes = { "obApi" }
};
来自IdentityServer4 ClientSecretValidator.cs的一个片段,其中包含您作为证据返回的确切错误 https://github.com/IdentityServer/IdentityServer4/blob/release/src/IdentityServer4/Validation/ClientSecretValidator.cs
var parsedSecret = await _parser.ParseAsync(context);
if (parsedSecret == null)
{
await RaiseFailureEvent("unknown", "No client id found");
_logger.LogError("No client identifier found");
return fail;
}
关于为JS,Android和iOS获取令牌的第二个问题,您可能需要考虑将为每个场景使用哪种OpenID Grant Type。我从IdentityServer开发人员看到的一般建议是使用Implicit flow for web applications和Authorization Code(或Hybrid)Flow。你可以在这里读更多关于它的内容: http://docs.identityserver.io/en/release/topics/grant_types.html