Error : InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
i have registered my API and web application both as multitenant but im not able to log in through another tenant,when im accessing the API through the app using the same tenant user in which app and api is registered it is letting me login,but cant get it done with multiple tenant.
when im adding instance as
"Instance": "https://login.microsoftonline.com",
it is working fine.
but when i add instance as
"Instance": "https://login.microsoftonline.com/common",
it throws error.
here is the code i have written inside startup.cs of web application
public void ConfigureServices(IServiceCollection services)
{
IdentityModelEventSource.ShowPII = true;
services.AddHttpClient<ITokenService, TokenService>();
services.AddMicrosoftIdentityWebAppAuthentication(Configuration).EnableTokenAcquisitionToCallDownstreamApi(new string[]
{ Configuration["APIConfig:APIScope"]}).AddInMemoryTokenCaches();
services.AddControllersWithViews(option =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
option.Filters.Add(new AuthorizeFilter(policy));
});
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
// Instead of using the default validation (validating against a single issuer value, as we do in
// line of business apps), we inject our own multitenant validation logic
ValidateIssuer = false,
// If the app is meant to be accessed by entire organizations, add your issuer validation logic here.
//IssuerValidator = (issuer, securityToken, validationParameters) => {
// if (myIssuerValidationLogic(issuer)) return issuer;
//}
};
options.Events = new OpenIdConnectEvents
{
OnTicketReceived = context =>
{
// If your authentication logic is based on users then add your logic here
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
context.Response.Redirect("/Error");
context.HandleResponse(); // Suppress the exception
return Task.CompletedTask;
},
// If your application needs to authenticate single users, add your user validation below.
//OnTokenValidated = context =>
//{
// return myUserValidationLogic(context.Ticket.Principal);
//}
};
});
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddRazorPages();
}
this is the code for aquiring token
public interface ITokenService
{
public Task<string> Get();
}
public class TokenService : ITokenService
{
private readonly HttpClient _httpClient;
private readonly string _APIScope = string.Empty;
private readonly string _APIBaseAddress = string.Empty;
private readonly ITokenAcquisition _tokenAquisition;
public TokenService(ITokenAcquisition tokenAquisition, HttpClient httpClient, IConfiguration configuration)
{
_httpClient = httpClient;
_tokenAquisition = tokenAquisition;
_APIScope = configuration["APIConfig:APIScope"];
_APIBaseAddress = configuration["APIConfig:APIBaseaddress"];
}
public async Task<string> Get()
{
await FindToken();
var response = await _httpClient.GetAsync($"{_APIBaseAddress}/weatherforecast");
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var content = await response.Content.ReadAsStringAsync();
var output = JsonConvert.DeserializeObject<string>(content);
return output;
}
throw new HttpRequestException("Invalid Response");
}
private async Task FindToken()
{
var accessToken = await _tokenAquisition.GetAccessTokenForUserAsync(new[] { _APIScope });
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
}