无法获得当前用户或授权

时间:2018-06-29 14:50:47

标签: c# angular asp.net-core

使用Angular 2 / ASP.NET Core 2.1应用程序。登录后,我可以从前端console.log JWT令牌,但是当我尝试使用[Authorize]属性访问控制器(AccountsController.cs)时,出现401错误。如果删除该属性,并尝试使用var currentUserId = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);获取当前用户,我会立即被发送回前端并通过解析器收到错误消息。

似乎当前的用户数据没有与请求一起发送到后端。还是没有存储?还是我无法正确访问它?

account-list.resolver.ts

import { Resolve, Router, ActivatedRouteSnapshot } from '@angular/router';
import { Account } from '../../_models/account';
import { Injectable } from '@angular/core';
import { AccountService } from '../../_services/account.service';
import { AlertifyService } from '../../_services/alertify.service';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/catch';

@Injectable()
export class AccountListResolver implements Resolve<Account[]> {
  pageSize = 5;
  pageNumber = 1;

  constructor(private accountService: AccountService,
    private router: Router,
    private alertify: AlertifyService) {
  }

  resolve(route: ActivatedRouteSnapshot): Observable<Account[]> {
    return this.accountService.getAccounts(this.pageNumber, this.pageSize).catch(error => {
      this.alertify.error('Problem retrieving data');
      this.router.navigate(['/dashboard']);
      return Observable.of(null);
    });
  }
}


account.service.ts

import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
import { Account } from '../_models/account';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { PaginatedResult } from '../_models/pagination';
import { HttpClient, HttpParams } from '@angular/common/http';

@Injectable()
export class AccountService {
  baseUrl = environment.apiUrl;

  constructor(private authHttp: HttpClient) { }

  getAccounts(page?, itemsPerPage?, accountParams?: any) {
    const paginatedResult: PaginatedResult<Account[]> = new PaginatedResult<Account[]>();
    let params = new HttpParams();

    if (page != null && itemsPerPage != null) {
      params = params.append('pageNumber', page);
      params = params.append('pageSize', itemsPerPage);
    }

    // if (accountParams != null) {
    //   params = params.append('paramName', accountParams.paramName);
    // }

    return this.authHttp
      .get<Account[]>(this.baseUrl + 'accounts', { observe: 'response', params })
      .map(response => {
        paginatedResult.result = response.body;
        if (response.headers.get('Pagination') != null) {
          paginatedResult.pagination = JSON.parse(response.headers.get('Pagination'));
        }

        return paginatedResult;
      });
  }
}


AccountsController

[Authorize]
[Route("api/[controller]")]
public class AccountsController : Controller
{
    private readonly IBaseRepository _repo;
    private readonly IMapper _mapper;

    public AccountsController(IBaseRepository repo, IMapper mapper)
    {
        _mapper = mapper;
        _repo = repo;
    }

    [HttpGet]
    public async Task<IActionResult> GetAccounts([FromQuery] AccountParams accountParams)
    {
        var currentUserId = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);
        //^^^WHERE IT BREAKS WHEN AUTHORIZATION ATTRIBUTE IS REMOVED

        //code to generate list of accounts to return
        accountParams.UserId = currentUserId;

        var accounts = await _repo.GetAccounts(accountParams);

        var accountsToReturn = _mapper.Map<IEnumerable<AccountForListDto>>(accounts);

        Response.AddPagination(accounts.CurrentPage, accounts.PageSize, accounts.TotalCount, accounts.TotalPages);

        return Ok(accountsToReturn);
    }
}


**编辑**

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    var key = Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value);

    services.AddDbContext<DataContext>(x => x
        .UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), b =>
            b.MigrationsAssembly(("MyApp.App")))
        .ConfigureWarnings(warnings => warnings.Ignore(CoreEventId.IncludeIgnoredWarning)));

    services.AddMvc()
        .AddJsonOptions(opt =>
        {
            opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        })
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/dist"; });

    services.AddTransient<Seed>();

    services.AddCors();

    services.AddAutoMapper();

    services.AddScoped<IAuthRepository, AuthRepository>();

    services.AddScoped<IBaseRepository, BaseRepository>();

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });

    services.AddScoped<LogUserActivity>();
}

public void ConfigureDevelopmentServices(IServiceCollection services)
{
    var key = Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value);

    services.AddDbContext<DataContext>(x => x
        .UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), b =>
            b.MigrationsAssembly(("MyApp.App")))
        .ConfigureWarnings(warnings => warnings.Ignore(CoreEventId.IncludeIgnoredWarning)));

    services.AddMvc()
        .AddJsonOptions(opt =>
        {
            opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        })
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/dist"; });

    services.AddTransient<Seed>();

    services.AddCors();

    services.AddAutoMapper();

    services.AddScoped<IAuthRepository, AuthRepository>();

    services.AddScoped<IBaseRepository, BaseRepository>();

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });

    services.AddScoped<LogUserActivity>();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler(builder =>
        {
            builder.Run(async context =>
            {
                context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;

                var error = context.Features.Get<IExceptionHandlerFeature>();
                if (error != null)
                {
                    context.Response.AddApplicationError(error.Error.Message);
                    await context.Response.WriteAsync(error.Error.Message);
                }
            });
        });
    }

    app.ConfigureSwagger(Assembly.GetExecutingAssembly());

    app.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());
    app.UseDefaultFiles();
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseSpaStaticFiles();

    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.UseProxyToSpaDevelopmentServer("http://localhost:4200");
            //spa.UseAngularCliServer(npmScript: "start");
        }
    });
}

1 个答案:

答案 0 :(得分:2)

您添加了JWT授权处理程序吗?

在您的startup.cs

  1. app.UseAuthentication()方法中是否有Configure
  2. 是在app.UseMvc()之前吗?
  3. 您的app.AddAuthentication()方法中是否有ConfigureServices
  4. 是在app.AddMvc()之前吗?
  5. 您的AddJwtBearer()方法挂起中是否有对ConfigureServices的调用 不打AddAuthentication()
  6. 在JwtBearer服务的选项中您是否具有正确的键?
  7. 如果JwtBearer不是您唯一的身份验证机制(例如,您还添加了Identity),您是否在Authorize属性中为承载指定了方案名称?

在您的配置中,好像您在configure方法中缺少app.UseAuthentication()。

因此您需要像这样将其放在app.UseMvc()之前;

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