401错误尝试在ASP.NET Core Web API上使用JWTBearerAuthentication

时间:2017-10-03 15:54:05

标签: asp.net azure authentication asp.net-web-api

我一直在使用各种教程来设置以下场景:

我有一个基于Ionic Framework构建的移动应用程序作为前端。我有一个ASP.Net Core 1.1.2 Web API作为后端。我想在允许他们访问API之前,在针对Azure Active Directory的移动应用程序中对用户进行身份验证。

以下是我对如何实现这一目标的概念性理解:

  1. 在AAD Portal中注册两个应用程序,一个作为应用程序类型Web App / API(称为WebAPI),另一个作为应用程序类型Native(称为MobileApp)。
  2. 添加MobileApp的权限以访问AAD中的委派权限中的WebAPI。
  3. 使用MobileApp从AAD请求令牌。
  4. 将令牌连同任何请求一起发送给WebAPI。
  5. 使用app.UseJwtBearerAuthentication中间件验证令牌并管理对WebAPI内容的访问。
  6. 我的第一个问题是,我的策略是否正确?如果是这样,我必须在实现中间件时做错事。

    我目前正在对应用程序中的AAD进行身份验证并接收令牌,其中包含以下内容:

    {
     "aud": "https://crm.mycompany.com/",
     "iss": "https://sts.windows.net/someID/",
     "iat": 1506539211,
     "nbf": 1506539211,
     "exp": 1506543111,
     "acr": "1",
     "aio": "someOtherID",
     "amr": [
     "pwd"
     ],
     "appid": "appID",
     "appidacr": "0",
     "e_exp": 262800,
     "family_name": "Walter",
     "given_name": "Philip",
     "ipaddr": "someAddress",
     "name": "Philip Walter",
     "oid": "someOtherID",
     "onprem_sid": "someOtherID",
     "puid": "stuff",
     "scp": "user_impersonation",
     "sub": "e_X7WlAoVS2vzXm1pr3kcDOrET7czcC0f8-YRU_2DJ8",
     "tenant_region_scope": "NA",
     "tid": "ourTenantID",
     "unique_name": "pwalter@advtis.com",
     "upn": "pwalter@advtis.com",
     "uti": "RLvLlibQHESwmujVBBdlAA",
     "ver": "1.0"
     }
    

    我可以通过Authentication: Bearer [token]标头将令牌发送到我的API,但收到401 Unauthorized响应。我一直在尝试使用以下教程来实现我的中间件:

    ASP.NET Core Token Authentication Guide

    看起来非常直接,但显然我错过了一些东西。这是我的Startup.cs:

    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }
    
        public IConfigurationRoot Configuration { get; }
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
    
            services.AddDbContext<AdvancedDBContext>();
            // Add framework services.
            services.AddCors();
            services.AddMvc();
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();
    
            app.UseCors(builder =>
            {
                builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
            });
    
            app.UseJwtBearerAuthentication(new JwtBearerOptions
            {
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidIssuer = "https://sts.windows.net/e618ef87-13b6-491b-babf-4e4f4139e3f3/",
    
                    ValidateAudience = true,
                    ValidAudience = "https://crm.mycompany.com"
    
                },
                AutomaticAuthenticate = true
            });
            app.UseMvc();
        }
    }
    }
    

    然后我根据需要使用[Authorize]属性来保护路由。

    我在这个实现与教程中的实现之间的主要区别在于我没有在任何地方指定密钥,但我不确定如何实现它,因为AAD发布了令牌。也许我需要从AAD那里得到一个?

    任何帮助都将不胜感激!

1 个答案:

答案 0 :(得分:0)

我们最近也意识到了这样的事情。根据我的理解,您需要指定一个应用程序客户端ID和一个秘密 - 需要在授权请求中传递的内容。在这里,您可以找到有关如何在Azure门户和PowerShell中执行此操作的简短教程:https://www.netiq.com/communities/cool-solutions/creating-application-client-id-client-secret-microsoft-azure-new-portal/