我已在我们的MVC应用中实施了OAuth2 client_credentials流程。我们的MVC应用程序实际上是此场景中的资源。我在为这个特定用例保护样本时遇到了很多困难,因为这个流程主要用于API访问,但我仍然这样做了。
我想与您分享一些实施细节,以询问有关我可能不知道的漏洞的任何信息。我绝不是安全专家,这就是把我带到这里的原因
在.NET Framework 4.5.2中,我使用了Microsoft.Owin库v3.0.1。我知道有更新的方法来设置这种东西,例如.NET Core和IdentityServer4,但正如我所说,我很难找到这个特定用例的可行样本,所以我尽我所能。
我实施了一个提供商:
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
private ClientService clientService;
public ApplicationOAuthProvider()
{
this.clientService = new ClientService();
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;
context.TryGetFormCredentials(out clientId, out clientSecret);
if (clientId == "XXXX" && clientSecret == "XXXXX")
{
context.Validated(clientId);
}
return base.ValidateClientAuthentication(context);
}
public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
{
var client = clientService.GetClient(context.ClientId);
var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, client.ClientName));
var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
context.Validated(ticket);
//context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
return base.GrantClientCredentials(context);
}
使用以下启动代码:
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
static Startup()
{
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(60),
//AllowInsecureHttp = true,
AuthenticationMode = AuthenticationMode.Active,
};
}
public void ConfigureAuth(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll)
.UseOAuthBearerTokens(OAuthOptions);
//app.UseOAuthBearerTokens(OAuthOptions);
}
}
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
ConfigureAuth(app);
}
}
然后创建了一个客户端应用程序,该应用程序也是一个网站,并最终获得了对资源(MVC应用程序)的访问权限。资源没有用户,因此没有登录屏幕。 Resource(now)具有令牌端点。客户端应用程序使用其凭据和(在经过身份验证后)向令牌端点发出请求,然后在对资源的后续请求中使用该令牌。 我找到了两种使用此令牌获取访问权限的方法。
我的问题是关于这种情况的漏洞:
假设客户端应用程序和服务器之间的所有通信都通过安全通道(https)进行,并且客户端应用程序能够以安全的方式维护凭据,那么获取或拦截访问令牌的可能性有多大?或者,此流程(或可能是另一个OAuth流程)中是否包含还包括客户端验证的方法?我意识到客户端已经通过client_id / client_secret进行了身份验证,但是当我询问验证时,我询问请求的来源(当然,假设验证方法不包括检查可能的内容)被恶意用户欺骗。)
还有一个额外的验证步骤,我应该包括我可能已经错过了 - 因为那里有很多信息,我尽力去冲刷,但我不能声称我有一个坚实的理解我到目前为止所阅读的所有内容
如果还有一个我错过的额外验证步骤,那么它如何适应这个(client_credentials)流程?
谢谢, 卡丽
答案 0 :(得分:1)
我找到了两种使用此令牌获取访问权限的方法。
- 在请求标头中包含访问令牌。 OR
- 将访问令牌包含为表单参数
这意味着您的访问令牌类型为Bearer令牌(因此,您还可以使用第三种方式发送访问令牌:使用带有查询参数的GET方法)。
获取或拦截访问令牌的可能性有多大?
或者,此流程中是否包含方法(或者可能是另一个OAuth流程) 还包括客户验证?
您有一个Bearer令牌,因此适用RFC-6750。 威胁缓解部分回答了您的问题:
首先,如果您的客户端应用和授权服务器之间的TLS版本(获取令牌)以及客户端应用和资源服务器之间的TLS版本,您的访问令牌可能会被披露 (给出令牌),有一个安全漏洞(摘录:这要求客户端和授权服务器之间的通信交互,以及客户端和资源服务器之间的交互,利用机密性和完整性保护。由于TLS必须实施并与本规范一起使用,因此它是通过通信渠道阻止令牌披露的首选方法。)
其次,您的访问令牌的另一种披露方式是在使用TLS加速器时。如RFC的同一部分所述:在某些部署中,包括那些利用负载平衡器的部署,与资源服务器的TLS连接在提供资源的实际服务器之前终止。这可能会使令牌在TLS连接终止的前端服务器和提供资源的后端服务器之间不受保护。
还有其他方法可以披露访问令牌。
解决方案不是实现另一个OAuth流,而是应用RFC第5.3节中的建议。总结一下,主要建议是:
这不在RFC中,但我会添加此建议:使用相互身份验证。这意味着客户端应用程序必须具有必须由资源服务器验证的X.509证书。这可以在您选择的特定Oauth2流中实现,因为资源服务器知道客户端应用程序(有一些替代流程,无法完成)。