Asp net core MVC controllers using cookie authentication and carrier api endpoints

I am working on a project using ASP.net CORE, where we have Angular 2 and the MVC and API must be protected by Azure AD.

Home / Index The MVC controller will launch Angular 2 SPA, and Home / Index should be protected by cookie authentication. I manage to get a token using the OpenIdConnectAuthentication - OnAuthorizationCodeReceived event.

I need to protect MVC controllers (there are several controllers besides Home / Index) using cookie-based authentication and APIs using bearer authentication, I can get a token from API to Angular, then use this token for every subsequent API call.

In the near future, mobile applications will appear that invoke the same API endpoints using Bearer tokens.

This was my starting point: https://docs.microsoft.com/en-us/azure/active-directory/active-directory-appmodel-v2-overview

Startup.cs

public void ConfigureServices(IServiceCollection services) { services.AddMvc().AddJsonOptions(config => { config.SerializerSettings.ContractResolver = new DefaultContractResolver(); }); services.AddAuthentication(sharedOptions => sharedOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseCookieAuthentication(new CookieAuthenticationOptions()); Authority = $"https://login.microsoftonline.com/AAAAA}"; ClientId = "BBBB"; ClientSecret = "CCCC"; Audience = "https://localhost:44333/"; app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions { ClientId = ClientId, Authority = Authority, PostLogoutRedirectUri = Audience, ResponseType = OpenIdConnectResponseType.CodeIdToken, GetClaimsFromUserInfoEndpoint = false, Events = new OpenIdConnectEvents { OnTokenValidated = TokenValidated, OnRemoteFailure = OnAuthenticationFailed, OnAuthorizationCodeReceived = OnAuthorizationCodeReceived } }); app.UseMvc(....); } 

Question:

How can I configure the API to use only the auth sounder and MVC to use cookies?

Update

Hi Adem Thanks for your reply.

I never tired of the 1st option, now everything will be in order. but I was tired of the second option before, and just tired, as shown below.

Added this below app.UseOpenIdConnectAuthentication (...

 app.UseJwtBearerAuthentication(new JwtBearerOptions { Authority = "https://login.microsoftonline.com/AAAA", Audience = "https://BBB.onmicrosoft.com/CCCC" }); 

For API Controller [Authorize(ActiveAuthenticationSchemes = "Bearer")]

For the MVC controller [Authorize(ActiveAuthenticationSchemes = "Cookies")]

When it gets to my home controller, it gets this error. The specified method is not supported.

this stack trace in Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler 1.HandleSignInAsync(SignInContext context) at Microsoft.AspNetCore.Authentication.AuthenticationHandler 1.d__66.MoveNext () --- The end of the stack trace from the previous place where the exception was thrown --- in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (task task) in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) in Microsoft.AspNetCore.Http.Authentication.Intal.Derminal.Intal.Dutal. stack traces from the previous place where the exception was thrown --- in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (task task) in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebugge rNotification (Task task) in Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler 1.<HandleRemoteCallbackAsync>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler 1.d__5.MoveNext () --- End the stack trace from the previous place where the exception was thrown --- in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (task task) in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) in the Microsoft.AspNetCore.Authentication.OpenIdConnect.ectConnect.ectConnect.ectNectConnect.OneIdConnect from pre yduschego place where it was chosen to the exclusion --- System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (task task) in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) in Microsoft.AspNetCore.Authentication.AuthenticationMiddleware 1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware 1.d__18.MoveNext () --- The end of the stack trace from the previous place where it was an exception is thrown --- in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (task task) in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) in Microsoft.AspNetCore.DiagnosticsMEx.andception

Update 2: I'm tired of setting up 2 different files for API and MVC, as shown below.

 app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder => { app.UseJwtBearerAuthentication(new JwtBearerOptions { Authority = Authority, Audience = Configuration["Authentication:AzureAd:Audience"] }); }); app.UseWhen(context => !context.Request.Path.StartsWithSegments("/api"), appBuilder => { app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions { ClientId = ClientId, Authority = Authority, PostLogoutRedirectUri = Audience, ResponseType = OpenIdConnectResponseType.CodeIdToken, GetClaimsFromUserInfoEndpoint = false, Events = new OpenIdConnectEvents { OnTokenValidated = TokenValidated, OnRemoteFailure = OnAuthenticationFailed, OnAuthorizationCodeReceived = OnAuthorizationCodeReceived } }); }); 

But the API still seems to be using a cookie. I could still see that the request has cookies in the request.

Thanks. Asanka

+6
source share
1 answer

One way is to use the application :

 app.UseWhen(context => <isApiRequest>, appBuilder => { appBuilder.UseJwtBearerAuthentication(); } app.UseWhen(context => <isNotApiRequest>, appBuilder => { appBuilder.UseCookieAuthentication(); } 

Note: you can insert your api with the prefix "/ api", in this case <isApiRequest> will be context.Request.Path.StartsWithSegment("/api")

Another way is to use AuthenticationScheme :

 app.UseCookieAuthentication(//....); app.UseJwtBearerAuthentication(//...); 

Then in the api action use the Bearer scheme:

 [Authoırize(ActiveAuthenticationSchemes = "Bearer")] public IActionResult ApiAction(){} 

For mvc actions use the Cookies scheme

 [Authoırize(ActiveAuthenticationSchemes = "Cookies")] public IActionResult MvcAction(){} 
+4
source

Source: https://habr.com/ru/post/1013115/


All Articles