在ASP.NET应用程序的控制器方法中获取请求的用户

时间:2019-05-26 03:44:10

标签: asp.net angular .net-core visual-studio-2019

我目前正在开发一个以angular为前端的ASP.NET Web应用程序。作为基础,Visual Studio 2019中针对ASP.NET angular的新模板具有个人身份验证

它在dotnet core 3.0 Preview 4上运行。

enter image description here

首先,通过模板应用程序的 register 接口创建一个用户。然后,当向后端的控制器发出请求时,我想获得发出请求的ApplicationUser。

有可能吗?我需要在前端的http请求的标头中放入任何类型的令牌吗?我需要在后端做些特别的事情吗?

当前,控制器中的http请求看起来像这样。

import { Component, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from "@angular/router";
import { error } from 'protractor';

@Component({
  selector: 'app-classes-component',
  templateUrl: './classes.component.html'
})
export class ClassesComponent {
  public classes: Class[];
  public http: HttpClient;
  public baseUrl: string;
  public courseCodeValue: string;

  constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string, private router: Router) {
    this.http = http;
    this.baseUrl = baseUrl;
    this.refreshCourses();
  }

  public refreshCourses() {
    this.http.get<Class[]>(this.baseUrl + 'api/Courses/GetCourses').subscribe(result => {
      this.classes = result;
    }, error => console.error(error));
  }
}

控制器看起来像这样:

    [Authorize]
    [Route("api/[controller]")]
    public class CoursesController : Controller
    {

        private readonly UserManager<ApplicationUser> _userManager;

        public CoursesController(UserManager<ApplicationUser> userManager)
        {
            _userManager = userManager;
        }


        [HttpGet("[action]")]
        public IEnumerable<CourseDto> GetCourses()
        {
            var user = _userManager.GetUserAsync(User).Result;

            // Here the user is null
            return user.Courses.Select(item => new CourseDto
            {
                CourseCode = item.CourseCode,
                CurrentGrade = item.CurrentGrade
            });

        }
    }

问题在于,当我尝试使用usermanager来获取发出http请求的用户时,我会得到null。所以我想知道我是否缺少什么。就像请求标头中的某种令牌一样?我在控制器端做错了吗?

编辑:这是 Startup.cs 代码

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

            services.AddDefaultIdentity<ApplicationUser>()
                .AddDefaultUI(UIFramework.Bootstrap4)
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddIdentityServer()
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

            services.AddAuthentication()
                .AddIdentityServerJwt();
            services.AddMvc(options => options.EnableEndpointRouting = false)
                .AddNewtonsoftJson();

            // In production, the Angular files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/dist";
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();

            app.UseAuthentication();
            app.UseIdentityServer();

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

            app.UseSpa(spa =>
            {
                // To learn more about options for serving an Angular SPA from ASP.NET Core,
                // see https://go.microsoft.com/fwlink/?linkid=864501

                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
        }
    }

1 个答案:

答案 0 :(得分:0)

您可以使用“ User.Identity.Name”获取发出请求的用户的UserId,然后将其传递给FindByIdAsync()。

var user =等待_userManager.FindByIdAsync(User.Identity.Name);

或针对UserId(User.Identity.Name)的数据库点击;

最适合您的

请让我知道是否可行。