We're trying to configure the server to work with an Azure B2C tenant using the OpenId section of the appsettings and we get this exception thrown when the token comes back in oursln.Portal.Web.Controllers.TokenAuthController:
{
"ClassName": "System.InvalidOperationException",
"Message": "IDX20803: Unable to obtain configuration from: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.",
"Data": null,
"InnerException": {
"ClassName": "System.IO.IOException",
"Message": "IDX20807: Unable to retrieve document from: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. HttpResponseMessage: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]', HttpResponseMessage.Content: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.",
"Data": null,
"InnerException": null,
"HelpURL": null,
"StackTraceString": " at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)\r\n at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)\r\n at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)",
"RemoteStackTraceString": null,
"RemoteStackIndex": 0,
"ExceptionMethod": null,
"HResult": -2146232800,
"Source": "Microsoft.IdentityModel.Protocols",
"WatsonBuckets": null
},
"HelpURL": null,
"StackTraceString": " at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)\r\n at Abp.AspNetZeroCore.Web.Authentication.External.OpenIdConnect.OpenIdConnectAuthProviderApi.ValidateToken(String token, String issuer, IConfigurationManager`1 configurationManager, CancellationToken ct)\r\n at Abp.AspNetZeroCore.Web.Authentication.External.OpenIdConnect.OpenIdConnectAuthProviderApi.GetUserInfo(String token)\r\n at oursln.Portal.Web.Controllers.TokenAuthController.GetExternalUserInfo(ExternalAuthenticateModel model) in C:\\Users\\rmorris\\source\\repos\\oursln-portal-server\\src\\oursln.Portal.Web.Core\\Controllers\\TokenAuthController.cs:line 516",
"RemoteStackTraceString": null,
"RemoteStackIndex": 0,
"ExceptionMethod": null,
"HResult": -2146233079,
"Source": "Microsoft.IdentityModel.Protocols",
"WatsonBuckets": null
}
Is this the ClaimsMapping issue? No matter what we have there we get this... here's what an attempt at the config looks like:
"OpenId": {
"IsEnabled": "true",
"ClientId": "<clientId>",
"Authority": "https://<tenantname>.b2clogin.com/<tenantId>/v2.0/",
"LoginUrl": "https://<tenantname>.b2clogin.com/<tenantname>.onmicrosoft.com/<policy>/oauth2/v2.0/authorize",
"ValidateIssuer": "false",
"ClaimsMapping": [
{
"claim": "unique_name",
"key": "name"
}
]
},
We'd prefer using the object ID or the email from the token but for now we're just trying to get something to work. Here's what's in the token during that exception:
{
"exp": 1603902874,
"nbf": 1603899274,
"ver": "1.0",
"iss": "https://<tenantname>.b2clogin.com/<tenantId>/v2.0/",
"sub": "<objectId>",
"aud": "<clientId>",
"nonce": "<nonce>",
"iat": 1603899274,
"auth_time": 1603899274,
"family_name": "<lastname>",
"given_name": "<firstname>",
"name": "<displayname>",
"emails": [
"<email>"
],
"tfp": "<policy>"
}
I've seen code modifying oursln.Portal.Web.Startup.AuthConfigurer, to deal with the email list in the returned token at a minimum, along with other customizations. I've tried changing that, to no effect. No matter what between the config and the auth configurer that exception is always thrown there. Could you offer any suggestions where to get started on this?
Let's say I want to write some service that can be called during a web request or possibly from a background worker outside of a web request. In the current case code for accessing blob storage. I'm just going to prefix the containers with tenant ID.
So far I've just been iterating over the tenants and fanning out recurrent jobs by enqueuing a job per tenant. Then just always having the tenant ID as a job arg as further jobs may be enqueued, passing the tenant IDs down into their dependencies.
What's the best way to handle this? Can I set an IAbpSession from a background job? Or do I always have to pass tenant IDs down from the job? I'd imagine just using another app service over the base service that gets the tenant from the session if I didn't want to do that explicitly from the entry point app service of a web request.
Using the ABP background job config settings during preinit to use hangfire is fine, there's a minor annoyance at restart however where jobs that were in the queue will fail until the IoC container registration in initialize. Is there a good way to prevent the hangfire server from processing until then?