I need to call secure Web API from Angular 9 application by presenting the Azure B2C JWT Bearer token. I am using Angular 9 with .NET CORE 3.1 Web API. I have managed to generate Azure B2C token but stuck to call secure Web API end-point as I am getting 401 unauthorized error. I am passing token in the header from angular.
testAPI1(){
console.log("calling test API ...");
const myheaders = new HttpHeaders({
'Content-Type': 'application/json; charset=utf-8',
'Authorization': this.authService.accessToken
});
this.http.get('https://localhost:5001/txn/v1/Dashboard/GetMessage', {headers: myheaders})
.subscribe((data)=>{
console.warn(data);
})
}
@Injectable()
export class AuthService implements OnInit{
constructor(
private oauthService: OAuthService,
private router: Router
){// other code}
public get accessToken() {
return this.oauthService.getAccessToken();
}
[Authorize]
[Route("txn/v1/[controller]/[action]")]
[EnableCors("CorsPolicy")]
[ApiController]
public class DashboardController : ControllerBase
{
[HttpGet]
public ActionResult<HelloMessage> GetMessage()
{
var result = new HelloMessage()
{
GivenName = "james",
ReturnMessage = "Dashboard@ Hello, Welcome to Digital tech"
};
return result;
}
public void ConfigureServices(IServiceCollection services)
{
//JWT Authentication
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(jwtConfig =>
{
jwtConfig.Audience = Configuration["AzureAdB2C:ResourceId"];
jwtConfig.Authority = $"{Configuration["AzureAdB2C:Instance"]}{Configuration["AzureAdB2C:TanantId"]}";
jwtConfig.RequireHttpsMetadata = false;
jwtConfig.SaveToken = true;
jwtConfig.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer =true,
ValidateAudience = true,
ValidateLifetime = true
};
});
//CORS policy
services.AddCors(options =>
options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin()));
According to the code you provided, you use the wrong Authority
. If we use Azure AD B2C, the Authority
should be likehttps://{your-tenant-name}.b2clogin.com/tfp/{your-tenant-domain}/{your-policy-name}/v2.0
.
For example
Web API Application
a. appsettings.json
.
{
"AzureAdB2C": {
"Instance": "https://<your tenant name>.b2clogin.com",
"ClientId": " your client id",
"Domain": "your tenant domain",
"TenantId": "your tenant id",
"SignUpSignInPolicyId": "your policy name"
},
...
}
b. Startup.cs
.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(jwtConfig =>
{
jwtConfig.Audience = Configuration["AzureAdB2C:ClientId"];
jwtConfig.Authority = $"{Configuration["AzureAdB2C:Instance"]}/tfp/{Configuration["AzureAdB2C:Domain"]}/{Configuration["AzureAdB2C:SignUpSignInPolicyId"]}/v2.0";
jwtConfig.RequireHttpsMetadata = false;
jwtConfig.SaveToken = true;
jwtConfig.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidAudience= jwtConfig.Audience,
ValidIssuer = $"{Configuration["AzureAdB2C:Instance"]}/{Configuration["AzureAdB2C:TenantId"]}/v2.0/"
};
});
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder => builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
});
services.AddControllers();
}
Angular component calling Web API end-point
public getMessage() {
const myheaders = new HttpHeaders({
'Content-Type': 'application/json; charset=utf-8',
'Authorization': 'Bearer '+this.oauthService.getAccessToken(),
'Access-Control-Allow-Origin':'*'
});
console.log(myheaders)
this.http.get("https://localhost:44389/weatherforecast", {headers: myheaders})
.subscribe(r => {
this.message = JSON.stringify(r)
console.log("message: ", this.message);
});
}