根据客户端 ID 授权对 API 的调用
Authorize calls to API based on Client Id
我有一个 C# API,它使用 IdentityServer3 来授权对方法的调用。
我想限制某个客户端可以访问哪些调用。客户端正在使用客户端凭证流程,我正在尝试找到一种方法来根据客户端 ID 授权调用。
是否有开箱即用的方法,或者我是否需要编写自定义过滤器?
您可以做的是拥有一个clientid 和一个clientSecret。您只需要实现一个逻辑来检查您的 clientid 和 clientSecret 是否有效以访问您的应用程序。
检查此示例并根据您的需要进行更新
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId = string.Empty;
string clientSecret = string.Empty;
Client client = null;
if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
{
context.TryGetFormCredentials(out clientId, out clientSecret);
}
if (context.ClientId == null)
{
//Remove the comments from the below line context.SetError, and invalidate context
//if you want to force sending clientId/secrects once obtain access tokens.
context.Validated();
//context.SetError("invalid_clientId", "ClientId should be sent.");
return Task.FromResult<object>(null);
}
using (AuthRepository _repo = new AuthRepository())
{
client = _repo.FindClient(context.ClientId);
}
if (client == null)
{
context.SetError("invalid_clientId", string.Format("Client '{0}' is not registered in the system.", context.ClientId));
return Task.FromResult<object>(null);
}
if (client.ApplicationType == Models.ApplicationTypes.NativeConfidential)
{
if (string.IsNullOrWhiteSpace(clientSecret))
{
context.SetError("invalid_clientId", "Client secret should be sent.");
return Task.FromResult<object>(null);
}
else
{
if (client.Secret != Helper.GetHash(clientSecret))
{
context.SetError("invalid_clientId", "Client secret is invalid.");
return Task.FromResult<object>(null);
}
}
}
if (!client.Active)
{
context.SetError("invalid_clientId", "Client is inactive.");
return Task.FromResult<object>(null);
}
context.OwinContext.Set<string>("as:clientAllowedOrigin", client.AllowedOrigin);
context.OwinContext.Set<string>("as:clientRefreshTokenLifeTime", client.RefreshTokenLifeTime.ToString());
context.Validated();
return Task.FromResult<object>(null);
}
你也可以看看这个教程here
如何添加身份验证管理器 - 如果您查看 Identity Server 样本,例如 "MVC Authentication",它会在启动时注册一个自定义身份验证管理器,然后使用简单的资源属性来保护每个控制器动作。
例如这进入你的启动
app.UseResourceAuthorization(new AuthorizationManager());
然后定义您的自定义 Auth 管理器 class,例如....
public class AuthorizationManager : ResourceAuthorizationManager
{
public override Task<bool> CheckAccessAsync(ResourceAuthorizationContext context)
{
switch (context.Resource.First().Value)
{
case "PageAuthCheck":
return AuthorizeContactDetails(context);
default:
return Nok();
}
}
private Task<bool> AuthorizeContactDetails(ResourceAuthorizationContext context)
{
switch (context.Action.First().Value)
{
case "Read":
return Eval(context.Principal.Identity.IsAuthenticated);
case "Write":
return Eval(context.Principal.HasClaim("role", "Admin"));
default:
return Nok();
}
}
}
之后您可以保护您的控制器操作,就像....
[ResourceAuthorize("Read", "PageAuthCheck")]
显然这只是一个使用用户声明角色检查的示例,但您应该能够轻松更改它以根据客户端 ID 进行保护
我有一个 C# API,它使用 IdentityServer3 来授权对方法的调用。
我想限制某个客户端可以访问哪些调用。客户端正在使用客户端凭证流程,我正在尝试找到一种方法来根据客户端 ID 授权调用。
是否有开箱即用的方法,或者我是否需要编写自定义过滤器?
您可以做的是拥有一个clientid 和一个clientSecret。您只需要实现一个逻辑来检查您的 clientid 和 clientSecret 是否有效以访问您的应用程序。
检查此示例并根据您的需要进行更新
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId = string.Empty;
string clientSecret = string.Empty;
Client client = null;
if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
{
context.TryGetFormCredentials(out clientId, out clientSecret);
}
if (context.ClientId == null)
{
//Remove the comments from the below line context.SetError, and invalidate context
//if you want to force sending clientId/secrects once obtain access tokens.
context.Validated();
//context.SetError("invalid_clientId", "ClientId should be sent.");
return Task.FromResult<object>(null);
}
using (AuthRepository _repo = new AuthRepository())
{
client = _repo.FindClient(context.ClientId);
}
if (client == null)
{
context.SetError("invalid_clientId", string.Format("Client '{0}' is not registered in the system.", context.ClientId));
return Task.FromResult<object>(null);
}
if (client.ApplicationType == Models.ApplicationTypes.NativeConfidential)
{
if (string.IsNullOrWhiteSpace(clientSecret))
{
context.SetError("invalid_clientId", "Client secret should be sent.");
return Task.FromResult<object>(null);
}
else
{
if (client.Secret != Helper.GetHash(clientSecret))
{
context.SetError("invalid_clientId", "Client secret is invalid.");
return Task.FromResult<object>(null);
}
}
}
if (!client.Active)
{
context.SetError("invalid_clientId", "Client is inactive.");
return Task.FromResult<object>(null);
}
context.OwinContext.Set<string>("as:clientAllowedOrigin", client.AllowedOrigin);
context.OwinContext.Set<string>("as:clientRefreshTokenLifeTime", client.RefreshTokenLifeTime.ToString());
context.Validated();
return Task.FromResult<object>(null);
}
你也可以看看这个教程here
如何添加身份验证管理器 - 如果您查看 Identity Server 样本,例如 "MVC Authentication",它会在启动时注册一个自定义身份验证管理器,然后使用简单的资源属性来保护每个控制器动作。
例如这进入你的启动
app.UseResourceAuthorization(new AuthorizationManager());
然后定义您的自定义 Auth 管理器 class,例如....
public class AuthorizationManager : ResourceAuthorizationManager
{
public override Task<bool> CheckAccessAsync(ResourceAuthorizationContext context)
{
switch (context.Resource.First().Value)
{
case "PageAuthCheck":
return AuthorizeContactDetails(context);
default:
return Nok();
}
}
private Task<bool> AuthorizeContactDetails(ResourceAuthorizationContext context)
{
switch (context.Action.First().Value)
{
case "Read":
return Eval(context.Principal.Identity.IsAuthenticated);
case "Write":
return Eval(context.Principal.HasClaim("role", "Admin"));
default:
return Nok();
}
}
}
之后您可以保护您的控制器操作,就像....
[ResourceAuthorize("Read", "PageAuthCheck")]
显然这只是一个使用用户声明角色检查的示例,但您应该能够轻松更改它以根据客户端 ID 进行保护