使用客户端凭据和OWIN Middleware OAuth

时间:2017-08-23 17:57:58

标签: oauth-2.0 client owin credentials verification

我已在我们的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-All‌​ow-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)具有令牌端点。客户端应用程序使用其凭据和(在经过身份验证后)向令牌端点发出请求,然后在对资源的后续请求中使用该令牌。 我找到了两种使用此令牌获取访问权限的方法。

  • 在请求标头中包含访问令牌。 OR
  • 将访问令牌包含为表单参数

我的问题是关于这种情况的漏洞:
假设客户端应用程序和服务器之间的所有通信都通过安全通道(https)进行,并且客户端应用程序能够以安全的方式维护凭据,那么获取或拦截访问令牌的可能性有多大?或者,此流程(或可能是另一个OAuth流程)中是否包含还包括客户端验证的方法?我意识到客户端已经通过client_id / client_secret进行了身份验证,但是当我询问验证时,我询问请求的来源(当然,假设验证方法不包括检查可能的内容)被恶意用户欺骗。) 还有一个额外的验证步骤,我应该包括我可能已经错过了 - 因为那里有很多信息,我尽力去冲刷,但我不能声称我有一个坚实的理解我到目前为止所阅读的所有内容 如果还有一个我错过的额外验证步骤,那么它如何适应这个(client_credentials)流程?

谢谢, 卡丽

1 个答案:

答案 0 :(得分:1)

  

我找到了两种使用此令牌获取访问权限的方法。

     
      
  • 在请求标头中包含访问令牌。 OR
  •   
  • 将访问令牌包含为表单参数
  •   

这意味着您的访问令牌类型为Bearer令牌(因此,您还可以使用第三种方式发送访问令牌:使用带有查询参数的GET方法)。

  

获取或拦截访问令牌的可能性有多大?

     

或者,此流程中是否包含方法(或者可能是另一个OAuth流程)   还包括客户验证?

您有一个Bearer令牌,因此适用RFC-6750。 威胁缓解部分回答了您的问题:

  • 首先,如果您的客户端应用和授权服务器之间的TLS版本(获取令牌)以及客户端应用和资源服务器之间的TLS版本,您的访问令牌可能会被披露 (给出令牌),有一个安全漏洞(摘录:这要求客户端和授权服务器之间的通信交互,以及客户端和资源服务器之间的交互,利用机密性和完整性保护。由于TLS必须实施并与本规范一起使用,因此它是通过通信渠道阻止令牌披露的首选方法。

  • 其次,您的访问令牌的另一种披露方式是在使用TLS加速器时。如RFC的同一部分所述:在某些部署中,包括那些利用负载平衡器的部署,与资源服务器的TLS连接在提供资源的实际服务器之前终止。这可能会使令牌在TLS连接终止的前端服务器和提供资源的后端服务器之间不受保护。

还有其他方法可以披露访问令牌。

解决方案不是实现另一个OAuth流,而是应用RFC第5.3节中的建议。总结一下,主要建议是:

  • 始终使用TLS,
  • 验证TLS证书链
  • 除了使用TLS保护之外还使用令牌加密:例如,使用客户端应用和资源服务器之间的共享密钥加密令牌
  • 不要在cookie中存储持有者令牌,
  • 发布短命的持票人代币
  • 发布范围承载令牌(使用受众限制)。

这不在RFC中,但我会添加此建议:使用相互身份验证。这意味着客户端应用程序必须具有必须由资源服务器验证的X.509证书。这可以在您选择的特定Oauth2流中实现,因为资源服务器知道客户端应用程序(有一些替代流程,无法完成)。