We have a Service Provider that was created in .net Core 3.1 using ComponentSpace .net core version 3.0.0
Got ComponentSpace working before in .net core but now it’s throwing an exception when
await _samlServiceProvider.ReceiveSsoAsync()
is called in our ServiceProvider from the Identity Provider.
We get the error message
The key{SOMEGUID LIKE fe0c5f73-807f-438f-82de-e316cf0427d5} was not found in the key ring.
Here is the stack trace - it is thrown directly from the ComponentSpace code
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)\n at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked)\n at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)\n at Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.Unprotect(IDataProtector protector, String protectedData)\n at ComponentSpace.Saml2.Session.CookieSsoSessionStore.DecodeCookieValueT(String encodedCookieValue)\n at ComponentSpace.Saml2.Session.CookieSsoSessionStore.GetCookieValue(
We are not doing anything with Data Protection APIs in our code - only ComponentSpace is using the Data Protection API. We just provide an implementation of IDistributedCache
In case it helps we have this in our
services.TryAddSingleton<IDistributedCache, MyDistributedCache>();
And MyDistributedCache has the following code (which calls an IDistributedCache implementation that stores data in Redis)
public class MyDistributedCache : IDistributedCache
{
private readonly ICacheRepository _cacheRepository;
public MyDistributedCache(ICacheRepository cacheRepository)
{
_cacheRepository = cacheRepository;
}
public byte[] Get(string key)
{
if (!_cacheRepository.TryGet(key, out byte[] value))
value = null;
return value;
}
public async Task<byte[]> GetAsync(string key, CancellationToken token = default)
{
var (found, value) = await _cacheRepository.TryGetAsync<byte[]>(key);
return found ? value : null;
}
public void Refresh(string key)
{
var value = Get(key);
Set(key, value, new DistributedCacheEntryOptions());
}
public async Task RefreshAsync(string key, CancellationToken token = default)
{
var value = await GetAsync(key, token);
await SetAsync(key, value, new DistributedCacheEntryOptions(), token);
}
public void Remove(string key)
{
_cacheRepository.Remove(key);
}
public async Task RemoveAsync(string key, CancellationToken token = default)
{
await _cacheRepository.RemoveAsync(key);
}
public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
{
_cacheRepository.TryAdd(key, value);
}
public async Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default)
{
await _cacheRepository.TryAddAsync(key, value);
}
Read the web farm guide and it said as long as IDistributedCache can be resolved everything should work.
It seems like this was working earlier - what should we do to fix this issue?
The CookieSsoSessionStore stores the SAML session state in the saml-session cookie value. The cookie value is protected using IDataProtectionProvider.
The CookieSsoSessionStore doesn’t make use of the IDistributedCache.
Did you want to store the SAML session state in the saml-session cookie itself (ie use CookieSsoSessionStore)?
Or did you want to store the SAML session state in your IDistributedCache implementation?
The CookieSsoSessionStore doesn't make use of the IDistributedCache.
Did you want to store the SAML session state in the saml-session cookie itself (ie use CookieSsoSessionStore)?
Or did you want to store the SAML session state in your IDistributedCache implementation?
I don't care where the saml session is stored - I prefer to just use the default.
My problem is that the default method of storing the cookiesessionstore with no changes to configuration is throwing an exception in my deployment - is there anything that needs to be configured with IDataProtectionProvider that I'm missing and is the reason why this is throwing this exception?
The CookieSsoSessionStore doesn't make use of the IDistributedCache.
Did you want to store the SAML session state in the saml-session cookie itself (ie use CookieSsoSessionStore)?
Or did you want to store the SAML session state in your IDistributedCache implementation?
I don't care where the saml session is stored - I prefer to just use the default.
My problem is that the default method of storing the cookiesessionstore with no changes to configuration is throwing an exception in my deployment - is there anything that needs to be configured with IDataProtectionProvider that I'm missing and is the reason why this is throwing this exception?[/quote]
This is the area where it is failing
Got ComponentSpace working before in .net core but now it's throwing an exception when
await _samlServiceProvider.ReceiveSsoAsync()
is called in our ServiceProvider from the Identity Provider.
We get the error message
The key{SOMEGUID LIKE fe0c5f73-807f-438f-82de-e316cf0427d5} was not found in the key ring.
Here is the stack trace - it is thrown directly from the ComponentSpace code
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)\n at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked)\n at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)\n at Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.Unprotect(IDataProtector protector, String protectedData)\n at ComponentSpace.Saml2.Session.CookieSsoSessionStore.DecodeCookieValueT(String encodedCookieValue)\n at ComponentSpace.Saml2.Session.CookieSsoSessionStore.GetCookieValue(
I wasn’t able to reproduce the issue. I used .NET Core 3.1 and SAML 3.0.0.
I added the following to the ExampleServiceProvider’s start-up.
// Add SAML SSO services.
services.AddSaml(Configuration.GetSection(“SAML”));
// Use a separate cookie name to avoid issues with the ExampleIdentityProvider
// which isn’t using the CookieSsoSessionStore.
services.Configure(options =>
{
options.CookieName = “my-saml-session”;
});
services.AddScoped<ISsoSessionStore, CookieSsoSessionStore>();
Can you reproduce the issue using the ExampleServiceProvider?
Are you using the default data protection setup?