amol
amol

Reputation: 1587

Can I use openid connect authentication and jwtbearer authentication scheme in one app?

I have an ASP.NET Core web app where the front-end is built in react and for the back-end, I have web APIs, both the things are placed in one web project. for authentication, I used Azure AD open Id connect authentication scheme.

Now I have a requirement where I need to expose some APIs to an external system using client credentials flow. so I am not sure how to implement this in the current web app as it already has the open id connect authentication scheme.

Any idea? Many thanks

Upvotes: 4

Views: 2349

Answers (3)

Sanjeevi Subramani
Sanjeevi Subramani

Reputation: 571

In Startup.cs

// Add services to the container.
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, (options) =>
 {
     options.TokenValidationParameters.ValidateIssuer = true;
     options.MetadataAddress = "metadataaddress";
     options.TokenValidationParameters.ValidAudience = "portal.com";
     // or any specific option used for your application
 });
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(
            options =>
            {
                builder.Configuration.Bind("AzureAd", options);
                // or any specific option used for your application
            });

In Controllers:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme + "," + OpenIdConnectDefaults.AuthenticationScheme)]
    [ApiController]
    [Route("[controller]")]
    public class SomeController : ControllerBase

This worked for me :)

Upvotes: 0

Kajen
Kajen

Reputation: 59

I had the same case and solved it this way:

Startup.cs

string[] scopes = new[]
            {
                "openid",
                "profile",
                "offline_access",
                "email",
                "scope_one",
                "scope_two",
            };

                services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.Authority = "https://my-own-indentity.com";
                    options.Audience = "Any_Audience";
                    options.RequireHttpsMetadata = false;
                    options.SaveToken = true;
                })  .AddOpenIdConnect("oidc", options =>
                {
                    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.Authority = "https://Authority.com";
                    options.ClientId = "*****";
                    options.ClientSecret = "******";
                    options.CallbackPath = "/callback";
                    options.ResponseType = "code";
                    options.ResponseType = OidcConstants.ResponseTypes.Code;
                    options.RequireHttpsMetadata = false;
                    options.SaveTokens = true;

                    options.Scope.Clear();
                    options.GetClaimsFromUserInfoEndpoint = true;

                    foreach (string scope in scopes)
                    {

                        options.Scope.Add(scope);
                    }
                });

To be authenticated by "AddJwtBearer" for controller:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("[controller]")]
[ApiController]
public class ProjectController : ControllerBase
{ 
   //your code
}

To be authenticated by "AddOpenIdConnect" for controller::

[Authorize(AuthenticationSchemes = "oidc")]
[ApiController]
[Route("api/[controller]")]
public class SomethingWithOpenIdController : Controller
{
 //your code
}

If you found another solution feel free to share, otherwise I hope this helps you.

Upvotes: 2

Carl Zhao
Carl Zhao

Reputation: 9519

You need to create two applications in Azure portal. At present, you already have an ASP.NET Core Web application, which represents the front-end application, so you need to create another application that represents the Web API, that is, the back-end application.

First, you need to expose the api of the back-end application protected by Azure, which can be configured according to the following process:

Azure portal>App registrations>Expose an API>Add a scope>Add a client application

enter image description here

Then you need to create the appRole of the back-end application, and then grant that role as an application permission to the client application.

enter image description here

Next, go to client application>API permissions>Add a permission>My APIs>your api application.

enter image description here

Finally, you need to obtain an access token using the client credential flow where no user is logged in:

enter image description here

Parse the token:

enter image description here

Finally, you can pass the token to the api application, and the api application will authenticate the client application by parsing the token.

Similar samples.

Upvotes: 2

Related Questions