【问题标题】:asp net core project MVC controllers using Cookie Authentication and api end points using Bearer使用 Cookie 身份验证的 asp net core 项目 MVC 控制器和使用 Bearer 的 api 端点
【发布时间】:2016-12-13 03:39:36
【问题描述】:

我正在使用 ASP .net CORE 开发一个项目,其中我们有 Angular 2、MVC 和 API,需要受 Azure AD 保护。

Home/Index MVC 控制器将启动 Angular 2 SPA,并且 Home/Index 需要通过 cookie 身份验证来保护。我设法使用 OpenIdConnectAuthentication - OnAuthorizationCodeReceived 事件获取令牌。

我需要使用基于 Cookie 的身份验证和使用承载身份验证的 API 来保护 MVC 控制器(除了 Home/Index 之外还有几个控制器),我可以将令牌从 API 获取到 Angular,然后将该令牌用于每个后续调用API。

在不久的将来,将会有移动应用程序使用 Bearer 令牌调用相同的 API 端点。

这是我的出发点: 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(....);
}

问题:

如何将 API 配置为仅使用“Bearer”身份验证和 MVC 以使用 Cookie?

更新

嗨,阿德姆 感谢您的回复。

我从不厌倦第一个选项,现在就试一试。 但我之前已经厌倦了第二个选项,只是厌倦了如下。

在 app.UseOpenIdConnectAuthentication(...

下面添加了这个
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
   Authority = "https://login.microsoftonline.com/AAAA",
   Audience = "https://BBB.onmicrosoft.com/CCCC"
});

对于 API 控制器[Authorize(ActiveAuthenticationSchemes = "Bearer")]

对于 MVC 控制器[Authorize(ActiveAuthenticationSchemes = "Cookies")]

当它碰到我的 Home Controller 时,会出现此错误 不支持指定的方法。

此堆栈跟踪 在 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler1.HandleSignInAsync(SignInContext context) at Microsoft.AspNetCore.Authentication.AuthenticationHandler1.d__66.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.AspNetCore.Http.Authentication.Internal.DefaultAuthenticationManager.d__14.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler1.<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.RemoteAuthenticationHandler1.d__5.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.d__15.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.d__18.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.d__6.MoveNext()

更新 2: 我已经厌倦了为 API 和 MVC 配置 2 种不同的身份验证,如下所示

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
      }
  });
});

但 API 似乎仍在使用 cookie 身份验证。我仍然可以看到请求中有 cookie。

谢谢 阿散卡

【问题讨论】:

  • 你应该在UseWhen方法中使用appBuilder而不是app

标签: asp.net asp.net-web-api asp.net-core single-sign-on


【解决方案1】:

一种方法是像这样分支应用程序

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

注意:您可以使用“/api”前缀来分支您的 api,在这种情况下,&lt;isApiRequest&gt; 将是 context.Request.Path.StartsWithSegment("/api")

另一种方式是使用AuthenticationScheme:

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

然后在 api 操作中使用 Bearer 方案:

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

对于 mvc 操作,请使用 Cookies 方案

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

【讨论】:

  • 我也遇到过类似的问题,搜了很多。最后使用此解决方案同时进行身份验证。同时做中间件。谢谢@adem
  • 谢谢 Adem Caglin 我参加了第二次考试
  • 当我使用这个解决方案时,一旦我删除它就会得到值..
猜你喜欢
  • 2020-03-09
  • 2023-04-01
  • 2018-01-27
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
  • 2018-12-10
  • 2021-06-15
  • 2021-04-15
相关资源
最近更新 更多