将基于Cookie的身份验证和基于令牌的身份验证同时用于api控制器

问题描述

我们有一个应用程序,该应用程序还包含一些应使用身份验证令牌调用的api控制器,还有一些其他api /常规控制器应使用基于开放id连接cookie的身份验证。以下是Startup.Auth.cs

中的代码
public void ConfigureAuth(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseKentorOwinCookieSaver();
        app.UseCookieAuthentication(new CookieAuthenticationoptions()
        { CookieSecure = CookieSecureOption.Always });

        app.USEOpenIdConnectAuthentication(CreateOptionsFromPolicy(PasswordResetPolicyId));
        app.USEOpenIdConnectAuthentication(CreateOptionsFromPolicy(SignUpSignInPolicyId));

        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationoptions
            {
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"],TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
                },});
    }

我们有一个diff Windows应用程序,该应用程序在添加用户凭据后应使用令牌调用api控制器方法。它确实调用了api方法,但作为响应,我们得到了一个html登录页面ui代码。收到OK状态,但是我们应该获取api方法返回的值,而不是此登录页面代码。由于身份验证会造成问题,因此无法执行此方法

解决方法

我的目标是确保网络和应用之间的清晰区分,如下所示:

Web应用程序特征

  • 使用网络托管解决方案
  • 未授权请求时,返回OAuth重定向到调用方

API特性

  • 使用API​​托管解决方案
  • 未授权请求时,返回401响应给呼叫者

这将解决桌面应用程序的问题。

代码分隔

旨在将您的Web后端和API代码分开-物理上作为单独的组件,或者在逻辑上在同一组件内。如果要使用后者,则通常是对API端点使用/ api根路径:

  • / myapp / myWebPage1
  • / myapp / myWebPage2
  • / myapp / api / myOperation1
  • / myapp / api / myOperation2

微软解决方案

在.Net Core中,Microsoft UseWhen 机制工作得很好,因此您可以编写如下代码:

app.UseWhen(
  ctx => ctx.Request.Path.StartsWithSegments(new PathString("/api")),api => app. UseWindowsAzureActiveDirectoryBearerAuthentication()
);
app.UseWhen(
  ctx => !ctx.Request.Path.StartsWithSegments(new PathString("/api")),api => app. UseCookieAuthentication()
);

如果您使用基于OWIN的C#,则可以通过extension method similar to this来实现相同的模式。