首页 文章

Angular 5和.NET Core 2的Windows身份验证

提问于
浏览
2

我的前端运行在localhost:4200上,后端运行在localhost:5000上我在后端和前端设置了Windows身份验证,如下所示

Program.cs中

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
     WebHost.CreateDefaultBuilder(args)
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseStartup<Startup>()
        .Build();
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<IISOptions>(options =>
    {
        options.AutomaticAuthentication = true;
    });

    services.AddAuthentication(IISDefaults.AuthenticationScheme);

    services.AddAuthorization(options => {
            options.AddPolicy("AllUsers", policy => {
                policy.AddAuthenticationSchemes(IISDefaults.AuthenticationScheme);
                policy.RequireRole("S - 1 - 1 - 0");
            });
     });

    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials());
    });

   var mvcBuilder = services.AddMvc();
   mvcBuilder.AddJsonOptions(opts => opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());
  services.AddAutoMapper(typeof(Startup));
  services.AddSingleton<IConfigurationRoot>(_config);
  services.AddRouting();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole();


    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();

    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();
    DefaultFilesOptions options = new DefaultFilesOptions();
    options.DefaultFileNames.Clear();
    options.DefaultFileNames.Add("index.html");
    app.UseDefaultFiles(options);

    app.UseAuthentication();

    app.UseCors("CorsPolicy");


    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });

    // Route all unknown requests to app root
    app.Use(async (context, next) =>
    {
        await next();

        // If there's no available file and the request doesn't contain an extension, we're probably trying to access a page.
        // Rewrite request to use app root
        if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
        {
            context.Request.Path = "/index.html"; // Put your Angular root page here 
            context.Response.StatusCode = 200; // Make sure we update the status code, otherwise it returns 404
            await next();
        }
    });

}

在控制器上,

[Authorize]
[Route("/api/service/testWinAuth")]
[EnableCors("CorsPolicy")]
public class TestWinAuth : Controller
{
 ....
}

在这个控制器的方法我有,

[Route("/{id}/{withVoids?}")]
[HttpGet]
[Authorize]
public Object testMethod(Int64? id, String withVoids)
{
    var userId = HttpContext.User.Identity.Name;

}

launchSettings.json

{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
      "applicationUrl": "http://localhost:5000/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "webapi": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "http://localhost:5001/"
    }
  }
}

在前端,我有以下设置:

proxy.conf.json

{
  "/api": {
    "target": "http://localhost:5000",
    "secure": false
  }
}

http请求设置为使用withCredentials = true选项

get(url: string, options?: RequestOptionsArgs): Observable<Response> {
  if (!options) {
    const headers = new Headers({ 'Content-Type': 'application/json' });
    options = new RequestOptions({ headers: headers, withCredentials: true });
  }
  // noinspection TypeScriptUnresolvedFunction
  return super.get(url, options)
    .map(r => r)
    .catch((error: any): Observable<Response> =>
      this.errorDisplayAndRedirect(error));
}

访问URL localhost:4200时,它会询问用户名和密码,并在验证后显示该页面 . 当我点击发送Get请求的按钮时,它再次请求身份验证,这次它没有进行身份验证,我收到401 Unauthorized错误 . 但是,当我使用URL直接访问后端时,它会询问用户名和密码并按预期进行身份验证 . 如何正确地将身份验证信息从前端传递到后端?

1 回答

  • 0

    在阅读了相关文章后:implementing windows authentication in an angular application and a stand-alone-web-api - 那个"You can’t use SupportsCredentials as true along with * for the origins.",我注意到以下代码行与上述内容相矛盾 .

    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials());
    });
    

    即当您允许凭据时,您也允许任何来源 .

    您是否考虑过替换.AllowAnyOrigin(),例如.WithOrigins(“http://localhost:4200”)或类似的东西?

    请记住,我没有使用您的代码,但遇到了同样的问题,但在提供了特定的来源后,它开始为我工作 .

    祝好运 .

相关问题