【问题标题】:Context.Principal getting null in case of Web API callContext.Principal 在 Web API 调用的情况下为空
【发布时间】:2020-11-20 14:09:48
【问题描述】:

我有一个使用 ASP.NET (.NET Framework 4.8) 和 ASP.NET WEB API 2、SQL SERVER 2016 开发的 Web 应用程序。我正在使用带有 OpenIDConnect(授权代码流)的 Azure AD。

在这种情况下,只有一个主机名为https://www.testwebapp.com的网络应用注册

我遵循https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow 中提到的所有步骤并实施了 Azure AD 身份验证。这是应用程序的详细信息:

主机:https://www.testwebapp.com API端点:https://www.testwebapp.com/services/api/test/current

导航到 URL:https://www.testwebapp.com 我被重定向到 Azure AD 登录页面,我在其中提供凭据,并且可以使用 jwt.io 查看声明。现在对 WEB API 项目的任何调用都来自 AngularJS 应用程序,这会导致授权失败。

在调试时,我可以看到上下文对象没有声明,因此也没有主体。

这里是在 API 项目的 WebApiConfig.cs 文件中注册的身份验证和授权文件管理器。

WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
      // Web API configuration and services
      config.Filters.Add(new SampleAuthenticationAttribute());
      config.Filters.Add(new SampleAuthorizationAttribute());
    }
}

SampleAuthenticationAttribute.cs:

public class SampleAuthenticationAttribute : ActionFilterAttribute, IAuthenticationFilter
    {
        private HttpAuthenticationContext _context;
        public Task AuthenticateAsync(HttpAuthenticationContext context, System.Threading.CancellationToken cancellationToken)
        {
            _context = context;
            return Task.FromResult(0);
        }

        public Task ChallengeAsync(HttpAuthenticationChallengeContext context, System.Threading.CancellationToken cancellationToken)
        {
            return Task.FromResult(context.Result);
        }
    }

SampleAuthorizationAttribute.cs:

public class SampleAuthorizationAttribute : AuthorizeAttribute
    {
        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            // retrieve principal and check authZ
            IPrincipal principal;
            if (!SecurityHelper.IsSecurityDisabled)
                principal = actionContext.RequestContext.Principal as IClaimsPrincipal;
            else
                principal = actionContext.RequestContext.Principal as System.Security.Claims.ClaimsPrincipal;
            if (principal != null && principal.Identity != null && principal.Identity.IsAuthenticated)
                return true;
            else
                return false;
        }

        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            var response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "unauthorized");
            response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Federation", "permission required."));
            actionContext.Response = response;
        }
    }

以下是 Web 应用程序的整体架构:

任何人都可以通过提供进一步的指导来帮助我吗?

【问题讨论】:

    标签: asp.net angularjs azure-active-directory msal .net-framework-4.8


    【解决方案1】:

    您的问题缺少一些细节,您如何在客户端(或者全部在服务器端?)将 Azure AD 集成到您的 Angular 应用程序中。看起来您没有为 Web API 调用添加授权标头(承载令牌)。

    如果您在客户端使用MSAL for Angular,它有MsalInterceptor 自动获取令牌并为您的后端API 调用添加授权标头。

    另外,对于后端的asp.net web api,请参考:

    【讨论】:

    • 感谢@krishg 的回复。在此实现中,前端和 API 项目都被视为使用相同应用程序池的单个应用程序。在此实现中,API 项目未在 AzureAD 中注册为单独的应用程序,因此无论何时从 angular 调用 webapis 都不需要持有者令牌。由于对 api 项目的调用在同一个应用程序边界内,所以理想情况下,我认为应该在调用之间维护声明并最终设置主体对象,这不会发生在这里。该应用程序在 ADFS 实施的情况下运行良好。
    • 每当从 Angular 调用 webapi 时,您如何在浏览器端的 http 请求中添加授权标头。我知道它可能部署在服务器端的同一个应用程序中,但最终当应用程序运行时,您的客户端组件正在浏览器端运行。除非你做某事,否则没有什么魔法可以自动添加标题。当您说“无论何时从 angular 调用 webapis 都不需要不记名令牌”,这是不正确的。
    • 在 ADFS 实现的情况下,相同的应用程序可以正常工作,在这种情况下,如果从 angularjs 对 webapi 进行任何调用,我也没有将不记名令牌添加到标头请求中。在这个实现中,API 项目没有单独的注册,因此我认为在这种情况下不需要传递不记名令牌。 angular 和 webapi 在这里一起形成一个应用程序,因此只在 Azure AD 中完成注册
    • 好的,那么您是否有机会从服务器端经过身份验证的 MVC 视图提供 Angular 组件?在这种情况下,您是否启用了 cookie 身份验证?不确定,因为您没有发布完整的服务器端启动代码。
    • 这是一个简单的 asp.net 容器应用程序,具有前端 angular 和后端 asp.net web api2。两者都形成一个应用程序。是的,我正在关注示例:docs.microsoft.com/en-us/azure/active-directory/develop/…。在容器 asp.net 应用程序中有一个 global.asx.cs 文件,其中包含 Application_PostAuthenticateRequest(object sender, EventArgs e) 事件的逻辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多