У меня проблемы с аутентификацией информации пользователя через токены Jwt. Я могу успешно войти в систему и зарегистрировать новых пользователей, и после входа в систему я могу console.log токен Jwt из внешнего интерфейса. Но когда я пытаюсь извлечь информацию из серверной части и контроллер использует атрибут [Authorize], я получаю следующие журналы:
Информация: запрос на запуск HTTP / 1.1 GET http://localhost:44325/api/accounts?pageNumber=1&pageSize=5
Информация: Маршрут соответствует {action = "GetAccounts", controller = "Accounts", page = ""}}. Выполнение действия MyApp.App.Controllers.AccountsController.GetAccounts (MyApp.App)
Отладка: план выполнения фильтров авторизации (в следующем порядке): Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter
Трассировка: Фильтр авторизации: перед выполнением OnAuthorizationAsync для фильтра Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.
Информация: авторизация не удалась.
Трассировка: Фильтр авторизации: после выполнения OnAuthorizationAsync для фильтра Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.
Информация: авторизация не выполнена для запроса в фильтре 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Трассировка: перед выполнением результата действия Microsoft.AspNetCore.Mvc.ChallengeResult.
Информация: выполнение ChallengeResult со схемами аутентификации ().
Информация: AuthenticationScheme: Носителю предъявлен вызов.
Трассировка: после выполнения результата действия Microsoft.AspNetCore.Mvc.ChallengeResult.
Информация: выполненное действие MyApp.App.Controllers.AccountsController.GetAccounts (MyApp.App) в 62.8374ms
Информация: запрос выполнен в 200.0118мс 401
Startup.cs
public void ConfigureDevelopmentServices(IServiceCollection services)
{
var key = Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value);
...
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
...
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
...
}
AccountsController.cs
[ServiceFilter(typeof(LogUserActivity))]
[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);
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);
}
}
счета-list.component.ts
import ...
@Component({
selector: "app-accounts",
templateUrl: "./account-list.component.html",
styleUrls: ["./account-list.component.css"]
})
export class AccountListComponent implements OnInit {
accounts: Account[];
accountParams: any = {};
pagination: Pagination;
constructor(private accountService: AccountService,
private route: ActivatedRoute,
private alertify: AlertifyService) {
}
ngOnInit() {
this.route.data.subscribe(data => {
this.accounts = data["accounts"].result;
this.pagination = data["accounts"].pagination;
});
}
loadAccounts() {
this.accountService.getAccounts(this.pagination.currentPage, this.pagination.itemsPerPage, this.accountParams)
.subscribe((res: PaginatedResult<Account[]>) => {
this.accounts = res.result;
this.pagination = res.pagination;
},
error => {
this.alertify.error(error);
});
}
}
account.service.ts
import ...
@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);
}
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;
});
}
счета-list.resolver.ts
import ...
@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);
});
}
}