如何创建将通过身份验证的默认Microsoft.IdentityModel.Tokens.SecurityKey?

时间:2019-08-06 18:17:35

标签: c# .net asp.net-core jwt asp.net-core-webapi

我的应用程序使用以下代码创建用于JWT身份验证的SecurityKey(在实现接口的KeyProvider对象内部):

//In my services setup code
public void ConfigureServices(IServiceCollection services) {
    var auth = services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme);
    auth.AddJwtBearer(opts =>
        opts.TokenValidationParameters = SetTokenValidation(keyProvider.GetSecurityKey())
    );
    ...

//In my KeyProvider object    
public SecurityKey GetSecurityKey() {
    if (key != null) return key;
    key = new X509SecurityKey(new X509Certificate2(
        GetJwtSignatureValidationKey()
    ));
    return key;
}

在此代码中,GetJwtSignatureValidationKey()调出到存储我们的密钥的服务器,获取适当的密钥,并将其作为字节数组返回。 我有两个问题需要解决。第一个,我找到了解决方案,但是第二个,我没有找到解决方案,尽管我认为应该能够以类似的方式解决这两个问题。

首先,对于单元测试,我不想真正调用我们的密钥服务器并获得实际的密钥。解决方案非常简单。在单元测试中,我仅使用实现上述GetSecurityKey()接口方法的TestKeyProvider对象。该测试对象仅返回抽象类SecurityKey的存根实现。一切正常,因为所有后续代码似乎都可以接受该对象,并且一切正常。

第二个问题是我尚未解决的问题。我的SecurityKey的简单存根实现被所有后续代码接受,这意味着一切都像授权用户一样工作。我还想模拟未获得授权的用户-换句话说,我需要一个有效的SecurityKey对象,该对象将使所有身份验证失败。实际上,我需要在两个地方使用它-一个用于单元测试,并且如果代码由于某种原因无法联系密钥服务器,我也想使用这样的对象。在那种情况下,我会记录错误,但是我不希望整个应用程序抛出异常,我希望所有调用都以401未经授权的响应简单地响应。

我尝试了很多事情,包括以下内容:

//These all throw an exception:
//CryptographicException: m_safeCertContext is an invalid handle.
key = new X509SecurityKey(new X509Certificate2());
key = new X509SecurityKey(new X509Certificate2((byte[])null));
//throws "Parameter cannot be null"
key = new X509SecurityKey(null);

//This throws an exception when constructing the certificate:
//WindowsCryptographicException: Cannot find the requested object
key = new X509SecurityKey(new X509Certificate2(bogusByteArray));

//These allow all traffic through as though they were all authorized:
key = new StubSecurityKey();
key = null;

理想情况下,我想找到一种实现StubSecurityKey的方法,以使其像有效的SecurityKey对象一样进行处理,但始终无法通过身份验证。

有什么想法吗?

0 个答案:

没有答案