Skip to content

Commit

Permalink
Managed SA (#33)
Browse files Browse the repository at this point in the history
* Update IdentityProvidersHandler.cs

* Update SpidCieOIDCConfiguration.cs

* Update RPOpenIdFederationMiddleware.cs

* Managed SA and code refactoring
  • Loading branch information
MithrandirTheWizard authored Sep 12, 2024
1 parent 359d801 commit f7c4f92
Show file tree
Hide file tree
Showing 126 changed files with 1,830 additions and 1,317 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ In particular, a 'SpidCie' section can be added to the configuration which has t
"AuthorityHints": [ "http://trust-anchor.org:8000" ],
"TrustMarks": [
{
"id": "https://www.spid.gov.it/openid-federation/agreement/sp-private",
"id": "https://preprod.oidc.registry.servizicie.interno.gov.it/intermediate/private",
"issuer": "https://preprod.oidc.registry.servizicie.interno.gov.it"
"trust_mark": "eyJhbGc...."
}
],
Expand All @@ -200,8 +201,18 @@ In particular, a 'SpidCie' section can be added to the configuration which has t
"MetadataPolicy": {},
"RelyingParties": [
{
"AuthorityHints": [
"http://aspnetcore.aggregator.org:5000/"
],
"Id": "http://aspnetcore.aggregator.org:5000/TestRP/",
"Name": "RP Test",
"OpenIdCoreCertificates": [
{
"Algorithm": "RS256", //Or RSA-OAEP-256
"Certificate": "base64",
"KeyUsage": "Signature" //Or Encryption
}
],
"OrganizationName": "RP Test",
"OrganizationType": "Public", // or Private
"HomepageUri": "http://aspnetcore.aggregator.org:5000/TestRP/",
Expand All @@ -210,6 +221,9 @@ In particular, a 'SpidCie' section can be added to the configuration which has t
"SecurityLevel": 2,
"Contacts": [ "[email protected]" ],
"LongSessionsEnabled": true,
"RedirectUris": [
"http://aspnetcore.aggregator.org:5000/TestRP/signin-oidc-spidcie"
]
"RequestedClaims": [
"Name",
"FamilyName",
Expand All @@ -218,9 +232,11 @@ In particular, a 'SpidCie' section can be added to the configuration which has t
"DateOfBirth",
"PlaceOfBirth"
],
"SecurityLevel": "L1", //Or L2 or L3
"TrustMarks": [
{
"Id": "https://registry.interno.gov.it/openid_relying_party/public/",
"Issuer": "http://aspnetcore.aggregator.org:5000",
"TrustMark": "eyJhbGc...."
}
]
Expand Down
7 changes: 4 additions & 3 deletions src/Spid.Cie.OIDC.AspNetCore.Tests/CieButtonTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
Expand All @@ -25,7 +26,7 @@ public async Task CieButtonTagHelper()
return Task.FromResult<TagHelperContent>(tagHelperContent);
});

var tagHelper = new Mvc.CieButtonTagHelper(new Mocks.MockIdentityProvidersHandler(false));
var tagHelper = new Mvc.CieButtonTagHelper(new UrlHelper(new Microsoft.AspNetCore.Mvc.ActionContext())/*new Mocks.MockIdentityProvidersHandler(false)*/);
tagHelper.ChallengeUrl = "http://127.0.0.1:8002/";
await tagHelper.ProcessAsync(context, tagHelperOutput);
}
Expand All @@ -47,7 +48,7 @@ public async Task CieButtonTagHelperEmptyCollection()
return Task.FromResult<TagHelperContent>(tagHelperContent);
});

var tagHelper = new Mvc.CieButtonTagHelper(new Mocks.MockIdentityProvidersHandler(true));
var tagHelper = new Mvc.CieButtonTagHelper(new UrlHelper(new Microsoft.AspNetCore.Mvc.ActionContext())/*new Mocks.MockIdentityProvidersHandler(true)*/);
tagHelper.ChallengeUrl = "http://127.0.0.1:8002/";
await tagHelper.ProcessAsync(context, tagHelperOutput);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public async Task TestFilterRequestedClaims()

var idp = new CieIdentityProvider()
{
EntityConfiguration = new IdPEntityConfiguration()
EntityConfiguration = new OPEntityConfiguration()
{
Metadata = new IdPMetadata_SpidCieOIDCConfiguration()
Metadata = new OPMetadata_SpidCieOIDCConfiguration()
{
OpenIdProvider = new Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public async Task DecodeJoseResponseOK()
{
var handler = new CustomHttpClientHandler(new MockRelyingPartySelector(),
new DefaultLogPersister(Mock.Of<ILogger<DefaultLogPersister>>()),
new MockCryptoService());
new MockCryptoService(), new MockAggregatorsHandler(), new MockHttpContextAccessor(false));

var resourceName = "Spid.Cie.OIDC.AspNetCore.Tests.IntegrationTests.userInfoResponse.jose";
using var stream = typeof(MockBackchannel).Assembly.GetManifestResourceStream(resourceName);
Expand All @@ -38,7 +38,7 @@ public async Task DecodeJoseResponseNoContent()
{
var handler = new CustomHttpClientHandler(new MockRelyingPartySelector(),
new DefaultLogPersister(Mock.Of<ILogger<DefaultLogPersister>>()),
new MockCryptoService());
new MockCryptoService(), new MockAggregatorsHandler(), new MockHttpContextAccessor(false));
var response = new HttpResponseMessage();
await Assert.ThrowsAnyAsync<Exception>(() => handler.DecodeJoseResponse(response));
}
Expand All @@ -48,7 +48,7 @@ public async Task DecodeJoseResponseNoRP()
{
var handler = new CustomHttpClientHandler(new MockRelyingPartySelector(true),
new DefaultLogPersister(Mock.Of<ILogger<DefaultLogPersister>>()),
new MockCryptoService());
new MockCryptoService(), new MockAggregatorsHandler(), new MockHttpContextAccessor(false));
var resourceName = "Spid.Cie.OIDC.AspNetCore.Tests.IntegrationTests.userInfoResponse.jose";
using var stream = typeof(MockBackchannel).Assembly.GetManifestResourceStream(resourceName);
using var reader = new StreamReader(stream);
Expand All @@ -64,7 +64,7 @@ public async Task DecodeJoseResponseNoEmptyContent()
{
var handler = new CustomHttpClientHandler(new MockRelyingPartySelector(),
new DefaultLogPersister(Mock.Of<ILogger<DefaultLogPersister>>()),
new MockCryptoService());
new MockCryptoService(), new MockAggregatorsHandler(), new MockHttpContextAccessor(false));
var response = new HttpResponseMessage();
response.Content = new StringContent(String.Empty, Encoding.UTF8, "application/jose");
await Assert.ThrowsAnyAsync<Exception>(() => handler.DecodeJoseResponse(response));
Expand All @@ -75,7 +75,7 @@ public async Task DecodeJoseResponseNoKeys()
{
var handler = new CustomHttpClientHandler(new MockRelyingPartySelector(false, true),
new DefaultLogPersister(Mock.Of<ILogger<DefaultLogPersister>>()),
new MockCryptoService());
new MockCryptoService(), new MockAggregatorsHandler(), new MockHttpContextAccessor(false));
var resourceName = "Spid.Cie.OIDC.AspNetCore.Tests.IntegrationTests.userInfoResponse.jose";
using var stream = typeof(MockBackchannel).Assembly.GetManifestResourceStream(resourceName);
using var reader = new StreamReader(stream);
Expand All @@ -91,7 +91,7 @@ public async Task DecodeJoseResponseWrongContent()
{
var handler = new CustomHttpClientHandler(new MockRelyingPartySelector(),
new DefaultLogPersister(Mock.Of<ILogger<DefaultLogPersister>>()),
new MockCryptoService());
new MockCryptoService(), new MockAggregatorsHandler(), new MockHttpContextAccessor(false));
var resourceName = "Spid.Cie.OIDC.AspNetCore.Tests.IntegrationTests.jwtOP.json";
using var stream = typeof(MockBackchannel).Assembly.GetManifestResourceStream(resourceName);
using var reader = new StreamReader(stream);
Expand All @@ -107,7 +107,7 @@ public async Task DecodeJoseResponseWrongContentType()
{
var handler = new CustomHttpClientHandler(new MockRelyingPartySelector(),
new DefaultLogPersister(Mock.Of<ILogger<DefaultLogPersister>>()),
new MockCryptoService());
new MockCryptoService(), new MockAggregatorsHandler(), new MockHttpContextAccessor(false));

var resourceName = "Spid.Cie.OIDC.AspNetCore.Tests.IntegrationTests.jwtOP.json";
using var stream = typeof(MockBackchannel).Assembly.GetManifestResourceStream(resourceName);
Expand All @@ -124,7 +124,7 @@ public async Task SendAsync()
{
var handler = new CustomHttpClientHandler(new MockRelyingPartySelector(true),
new DefaultLogPersister(Mock.Of<ILogger<DefaultLogPersister>>()),
new MockCryptoService());
new MockCryptoService(), new MockAggregatorsHandler(), new MockHttpContextAccessor(false));
var request = new HttpRequestMessage();
request.Content = new StringContent(string.Empty);
request.RequestUri = new Uri("http://127.0.0.1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.AspNetCore.TestHost;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Spid.Cie.OIDC.AspNetCore.Configuration;
using Spid.Cie.OIDC.AspNetCore.Enums;
using Spid.Cie.OIDC.AspNetCore.Helpers;
using Spid.Cie.OIDC.AspNetCore.Models;
using System;
Expand Down Expand Up @@ -47,7 +48,7 @@ public TestSettings(Action<SpidCieOptions> configure)
Contacts = new() { "[email protected]" },
AuthorityHints = new() { "http://127.0.0.1:8000/oidc/op/" },
RedirectUris = new() { "http://127.0.0.1:5000/signin-spidcie" },
SecurityLevel = SecurityLevel.L2,
SecurityLevel = SecurityLevels.L2,
LongSessionsEnabled = false,
TrustMarks = new()
{
Expand All @@ -57,7 +58,21 @@ public TestSettings(Action<SpidCieOptions> configure)
TrustMark = "eyJhbGciOiJSUzI1NiIsImtpZCI6IkZpZll4MDNibm9zRDhtNmdZUUlmTkhOUDljTV9TYW05VGM1bkxsb0lJcmMiLCJ0eXAiOiJ0cnVzdC1tYXJrK2p3dCJ9.eyJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgwMDAvIiwic3ViIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwLyIsImlhdCI6MTY0NzI3Njc2NiwiaWQiOiJodHRwczovL3d3dy5zcGlkLmdvdi5pdC9jZXJ0aWZpY2F0aW9uL3JwIiwibWFyayI6Imh0dHBzOi8vd3d3LmFnaWQuZ292Lml0L3RoZW1lcy9jdXN0b20vYWdpZC9sb2dvLnN2ZyIsInJlZiI6Imh0dHBzOi8vZG9jcy5pdGFsaWEuaXQvaXRhbGlhL3NwaWQvc3BpZC1yZWdvbGUtdGVjbmljaGUtb2lkYy9pdC9zdGFiaWxlL2luZGV4Lmh0bWwifQ.uTbO9gbx3cyNgs4LS-zij9kOC1alQuxFytsPNjwloGdnoGj_4PCJasMxmKVyUJXkXKQGeiG69oXBnf6sL9McYP6RYklhqFBR0hW4X5H5qc4vDYetDo8ajzocMZm050YzTrUObwy3OLOQRGLuWvg2uifRy8YCC0xD0OxoeBaEeURM_zkU3PFQ76RLP2W8b63J37behBevrO1lKJHhyfE4oJ6qFpR2Vk0367mMu7c0vhuTZYw8a5UkDbYR4L77vyzVlpE1duL5ibvREV4YMuMtWbI9fn1nlpgtmTp1Z089PN_PHVQHBrmHRG6jcwU6JCOdNXFBTsXtglU-xRng99Z6aQ"
}
},
OpenIdCoreCertificates = new() { certificate },
OpenIdCoreCertificates =
[
new RPOpenIdCoreCertificate
{
Algorithm = "RS256",
Certificate = certificate,
KeyUsage = KeyUsageTypes.Signature
},
new RPOpenIdCoreCertificate
{
Algorithm = "RSA-OAEP-256",
Certificate = certificate,
KeyUsage = KeyUsageTypes.Encryption
},
],
OpenIdFederationCertificates = new() { certificate },
RequestedClaims = new()
{
Expand Down
11 changes: 6 additions & 5 deletions src/Spid.Cie.OIDC.AspNetCore.Tests/Mocks/MockBackchannel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Spid.Cie.OIDC.AspNetCore.Configuration;
using Microsoft.AspNetCore.Http;
using Spid.Cie.OIDC.AspNetCore.Configuration;
using Spid.Cie.OIDC.AspNetCore.Services;
using System;
using System.IO;
Expand All @@ -13,10 +14,10 @@ internal partial class TestSettings
{
internal class MockBackchannel : CustomHttpClientHandler
{
public MockBackchannel(IRelyingPartySelector rpSelector,
ILogPersister logPersister,
ICryptoService cryptoService)
: base(rpSelector, logPersister, cryptoService)
public MockBackchannel(IRelyingPartySelector rpSelector, ILogPersister logPersister,
ICryptoService cryptoService, IAggregatorsHandler aggregatorsHandler,
IHttpContextAccessor contextAccessor)
: base(rpSelector, logPersister, cryptoService, aggregatorsHandler, contextAccessor)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ public async Task<IEnumerable<IdentityProvider>> GetIdentityProviders()
new SpidIdentityProvider(){
Uri = "http://127.0.0.1:8000/oidc/op/",
SupportedAcrValues = new() { SpidCieConst.SpidL2, SpidCieConst.SpidL1, SpidCieConst.SpidL3 },
EntityConfiguration = new IdPEntityConfiguration(){
EntityConfiguration = new OPEntityConfiguration(){
Issuer = "http://127.0.0.1:8000/oidc/op/",
Metadata = new IdPMetadata_SpidCieOIDCConfiguration(){
Metadata = new OPMetadata_SpidCieOIDCConfiguration(){
OpenIdProvider = conf
}
}
},
new CieIdentityProvider(){
Uri = "http://127.0.0.1:8002/oidc/op/",
SupportedAcrValues = new() { SpidCieConst.SpidL2, SpidCieConst.SpidL1, SpidCieConst.SpidL3 },
EntityConfiguration = new IdPEntityConfiguration(){
EntityConfiguration = new OPEntityConfiguration(){
Issuer = "http://127.0.0.1:8002/oidc/op/",
Metadata = new IdPMetadata_SpidCieOIDCConfiguration(){
Metadata = new OPMetadata_SpidCieOIDCConfiguration(){
OpenIdProvider = conf
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Options;
using Spid.Cie.OIDC.AspNetCore.Configuration;
using Spid.Cie.OIDC.AspNetCore.Enums;
using Spid.Cie.OIDC.AspNetCore.Models;
using System;
using System.Security.Cryptography.X509Certificates;
Expand Down Expand Up @@ -34,7 +35,7 @@ public SpidCieOptions Get(string name)
Contacts = new() { "[email protected]" },
AuthorityHints = new() { "http://127.0.0.1:8000/" },
RedirectUris = new() { "http://127.0.0.1:5000/signin-oidc" },
SecurityLevel = SecurityLevel.L2,
SecurityLevel = SecurityLevels.L2,
LongSessionsEnabled = false,
TrustMarks = new()
{
Expand All @@ -44,7 +45,21 @@ public SpidCieOptions Get(string name)
TrustMark = "eyJhbGciOiJSUzI1NiIsImtpZCI6IkZpZll4MDNibm9zRDhtNmdZUUlmTkhOUDljTV9TYW05VGM1bkxsb0lJcmMiLCJ0eXAiOiJ0cnVzdC1tYXJrK2p3dCJ9.eyJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgwMDAvIiwic3ViIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwLyIsImlhdCI6MTY0NzI3Njc2NiwiaWQiOiJodHRwczovL3d3dy5zcGlkLmdvdi5pdC9jZXJ0aWZpY2F0aW9uL3JwIiwibWFyayI6Imh0dHBzOi8vd3d3LmFnaWQuZ292Lml0L3RoZW1lcy9jdXN0b20vYWdpZC9sb2dvLnN2ZyIsInJlZiI6Imh0dHBzOi8vZG9jcy5pdGFsaWEuaXQvaXRhbGlhL3NwaWQvc3BpZC1yZWdvbGUtdGVjbmljaGUtb2lkYy9pdC9zdGFiaWxlL2luZGV4Lmh0bWwifQ.uTbO9gbx3cyNgs4LS-zij9kOC1alQuxFytsPNjwloGdnoGj_4PCJasMxmKVyUJXkXKQGeiG69oXBnf6sL9McYP6RYklhqFBR0hW4X5H5qc4vDYetDo8ajzocMZm050YzTrUObwy3OLOQRGLuWvg2uifRy8YCC0xD0OxoeBaEeURM_zkU3PFQ76RLP2W8b63J37behBevrO1lKJHhyfE4oJ6qFpR2Vk0367mMu7c0vhuTZYw8a5UkDbYR4L77vyzVlpE1duL5ibvREV4YMuMtWbI9fn1nlpgtmTp1Z089PN_PHVQHBrmHRG6jcwU6JCOdNXFBTsXtglU-xRng99Z6aQ"
}
},
OpenIdCoreCertificates = _noKeys ? new() : new() { certificate },
OpenIdCoreCertificates = _noKeys ? new() : new()
{
new RPOpenIdCoreCertificate
{
Algorithm = "RS256",
Certificate = certificate,
KeyUsage = KeyUsageTypes.Signature
},
new RPOpenIdCoreCertificate
{
Algorithm = "RSA-OAEP-256",
Certificate = certificate,
KeyUsage = KeyUsageTypes.Encryption
}
},
OpenIdFederationCertificates = _noKeys ? new() : new() { certificate },
}); ;
}
Expand Down
49 changes: 34 additions & 15 deletions src/Spid.Cie.OIDC.AspNetCore.Tests/Mocks/MockTrustChainManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,61 @@

namespace Spid.Cie.OIDC.AspNetCore.Tests.Mocks;

internal class MockTrustChainManager : ITrustChainManager
class MockTrustChainManager : ITrustChainManager
{
public async Task<IdPEntityConfiguration?> BuildTrustChain(string url)
public async Task<OPEntityConfiguration?> BuildTrustChain(string url)
{
await Task.CompletedTask;
var result = new IdPEntityConfiguration()

var result = new OPEntityConfiguration()
{
Issuer = url,
Metadata = new IdPMetadata_SpidCieOIDCConfiguration()
Metadata = new OPMetadata_SpidCieOIDCConfiguration()
{
OpenIdProvider = new Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration()
}
};

result.Metadata.OpenIdProvider.AdditionalData.Add("op_uri", "test");
result.Metadata.OpenIdProvider.AdditionalData.Add("op_name", "test");
result.Metadata.OpenIdProvider.AdditionalData.Add("logo_uri", "test");
result.Metadata.OpenIdProvider.AdditionalData.Add("organization_name", "test");
result.Metadata.OpenIdProvider.AcrValuesSupported.Add("test");

return result;
}

public TrustChain? GetResolvedTrustChain(string sub, string anchor)
public async Task<RPEntityConfiguration?> BuildRPTrustChain(string url)
{
return new TrustChain()
await Task.CompletedTask;

var result = new RPEntityConfiguration()
{
ExpiresOn = System.DateTimeOffset.MaxValue,
Chain = new System.Collections.Generic.List<string> { "test1", "test2" },
OpConf = new IdPEntityConfiguration()
Issuer = url,
Metadata = new RPMetadata_SpidCieOIDCConfiguration()
{
Issuer = sub,
Metadata = new IdPMetadata_SpidCieOIDCConfiguration()
FederationEntity = new RP_SpidCieOIDCFederationEntity
{
OpenIdProvider = new Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration()

},
OpenIdRelyingParty = new RP_SpidCieOIDCConfiguration
{

}
},
TrustAnchorUsed = anchor
}
};

return result;
}

public TrustChain<T>? GetResolvedTrustChain<T>(string sub, string anchor) where T : EntityConfiguration
{
return typeof(T).Equals(typeof(OPEntityConfiguration)) ? new OPEntityConfiguration()
{
ExpiresOn = System.DateTimeOffset.MaxValue,
} as TrustChain<T> : typeof(T).Equals(typeof(RPEntityConfiguration)) ? new RPEntityConfiguration
{
ExpiresOn = System.DateTimeOffset.MaxValue,
} as TrustChain<T> : default;
}
}
}
Loading

0 comments on commit f7c4f92

Please sign in to comment.