мне нужно создать сайт с angular6 и aspcore.
Я создаю сервер с ядром ASP и создаю этот токен:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhYzQ3NjJjZi0xNDdmLTJmZmYtZTQ1Yy05ZDNjNjJkYTAwMDEiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQ0MzkwLyIsImlhdCI6MTU0NDg2OTU1OSwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiIzMDAyIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImtpYUBraWEuY29tIiwiRGlzcGxheU5hbWUiOiLYotix2LQg2KjYsdmH2KfZhtuMIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9zZXJpYWxudW1iZXIiOiI0Njg0NjM0NjQiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3VzZXJkYXRhIjoiMzAwMiIsIm5iZiI6MTU0NDg2OTU1OSwiZXhwIjoxNTQ0ODY5Njc5LCJhdWQiOiJBbnkifQ.zhW3aoRKGaoy-wEbO7RnbdQmxCXSy50pSaqO1OoEwe8",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiMDEyNTQxYi0yZDljLTE2N2UtZDM0Ni1hZjNlNWRiYjMzYzgiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQ0MzkwLyIsImlhdCI6MTU0NDg2OTU1OSwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9zZXJpYWxudW1iZXIiOiIwZGMwMTRmNDc1NTQ1Y2MyYjEwNzUzZjU1YTFlOTQxNyIsIm5iZiI6MTU0NDg2OTU1OSwiZXhwIjoxNTQ0ODczMTU5LCJhdWQiOiJBbnkifQ.8vwTvDJcT8MoOfvqVb7gGzSxbll2_u91bArumJDW65k"
}
, и это мой сервис для поиска userInfo:
public UserInfo(username:string):Observable<IUser>{
return this.http.get<IUser>(`${this.baseUrl+'GetUserInfo/'}${username}`,{headers:{
'Content-Type': 'application/json; charset=utf-8',
'Authorization': 'Bearer ' + this.broserStorage.GetLocalStorage('AccessToken')+this.broserStorage.GetLocalStorage('RefreshToken'),
},
})
.pipe(
tap((user: IUser) => this.log(`GetUserInfo user w/ email=${user}`)),
catchError(this.handleError<IUser>('GetUserInfo user'))
);
}
Я отправляю запрос, но он показывает мне эту ошибку:
Сбой пользователя GetUserInfo: Http-сбой для https://localhost:44390/api/user/GetUserInfo/kia@kia.com: 401 Несанкционированный
в чем проблема ?С сервера или Angular?
этот код с сервера:
[HttpGet("GetUserInfo/{username}")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public async Task<IActionResult> GetUSerInfo(string username)
{
UserRoleViewModel URVM = new UserRoleViewModel();
var user = await _applicationUserManager.FindByNameAsync(username);
if (user != null)
{
var roles = await _applicationUserManager.GetRolesAsync(user);
var roleName = await _applicationRoleManager.FindRoleByNameList(roles[0]);
URVM.Id = user.Id;
URVM.Email = user.Email;
URVM.BirthDate = user.BirthDate;
URVM.CreatedDateTime = user.CreatedDateTime;
URVM.FirstName = user.FirstName;
URVM.IsActive = user.IsActive;
URVM.PhoneNmuberConfirmed = user.PhoneNumberConfirmed;
URVM.IsEmailPublic = user.IsEmailPublic;
URVM.LastName = user.LastName;
URVM.TwoFactorEnabled = user.TwoFactorEnabled;
URVM.EmailConfirmed = user.EmailConfirmed;
URVM.LockoutEnabled = user.LockoutEnabled;
URVM.LastVisitDateTime = user.LastVisitDateTime;
URVM.Location = user.Location;
URVM.PhotoFileName = user.PhotoFileName;
URVM.RoleLevel = roleName.RoleLevel;
URVM.Description = roleName.Description;
URVM.roleId = roleName.Id;
URVM.desplayName = user.FirstName + " " + user.LastName;
return Ok(URVM);
}
return BadRequest();
}
этот запуск:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.WithOrigins("http://localhost:4200") //Note: The URL must be specified without a trailing slash (/).
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddIdentity<User, Role>().AddUserStore<ApplicationUserStore>()
.AddUserManager<ApplicationUserManager>()
.AddRoleStore<ApplicationRoleStore>()
.AddRoleManager<ApplicationRoleManager>()
.AddSignInManager<ApplicationSignInManager>()
.AddDefaultTokenProviders();
services
.AddAuthentication(options =>
{
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = Configuration["BearerTokens:Issuer"], // site that makes the token
ValidateIssuer = false, // TODO: change this to avoid forwarding attacks
ValidAudience = Configuration["BearerTokens:Audience"], // site that consumes the token
ValidateAudience = false, // TODO: change this to avoid forwarding attacks
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["BearerTokens:Key"])),
ValidateIssuerSigningKey = true, // verify signature to avoid tampering
ValidateLifetime = true, // validate the expiration
ClockSkew = TimeSpan.Zero // tolerance for the expiration date
};
cfg.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(JwtBearerEvents));
logger.LogError("Authentication failed.", context.Exception);
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
var tokenValidatorService = context.HttpContext.RequestServices.GetRequiredService<ITokenValidatorService>();
return tokenValidatorService.ValidateAsync(context);
},
OnMessageReceived = context =>
{
return Task.CompletedTask;
},
OnChallenge = context =>
{
var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(JwtBearerEvents));
logger.LogError("OnChallenge error", context.Error, context.ErrorDescription);
return Task.CompletedTask;
}
};
});
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseExceptionHandler(appBuilder =>
{
appBuilder.Use(async (context, next) =>
{
var error = context.Features[typeof(IExceptionHandlerFeature)] as IExceptionHandlerFeature;
if (error != null && error.Error is SecurityTokenExpiredException)
{
context.Response.StatusCode = 401;
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject(new
{
State = 401,
Msg = "token expired"
}));
}
else if (error != null && error.Error != null)
{
context.Response.StatusCode = 500;
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject(new
{
State = 500,
Msg = error.Error.Message
}));
}
else
{
await next();
}
});
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseCors("CorsPolicy");
app.UseAuthentication();
var scopeFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "areas",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
);
});
}
Редактировать
я добавляю этот класс:
@Injectable()
export class AuthInterceptorService implements HttpInterceptor {
private delayBetweenRetriesMs = 1000;
private numberOfRetries = 3;
private authorizationHeader = "Authorization";
constructor(
private tokenStoreService: TokenstoreService,
private router: Router) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const accessToken = this.tokenStoreService.getRawAuthToken(AuthTokenType.AccessToken);
if (accessToken) {
console.log('in if')
request = request.clone({
headers: request.headers.set(this.authorizationHeader, `Bearer ${accessToken}`)
});
return next.handle(request).pipe(
retryWhen(errors => errors.pipe(
mergeMap((error: HttpErrorResponse, retryAttempt: number) => {
if (retryAttempt === this.numberOfRetries - 1) {
console.log(`HTTP call '${request.method} ${request.url}' failed after ${this.numberOfRetries} retries.`);
return throwError(error); // no retry
}
switch (error.status) {
case 400:
case 404:
return throwError(error); // no retry
}
return of(error); // retry
}),
delay(this.delayBetweenRetriesMs),
take(this.numberOfRetries)
)),
catchError((error: any, caught: Observable<HttpEvent<any>>) => {
console.error({ error, caught });
if (error.status === 401 || error.status === 403) {
const newRequest = this.getNewAuthRequest(request);
if (newRequest) {
console.log("Try new AuthRequest ...");
return next.handle(newRequest);
}
this.router.navigate(["/accessDenied"]);
}
return throwError(error);
})
);
} else {
// login page
return next.handle(request);
}
}
getNewAuthRequest(request: HttpRequest<any>): HttpRequest<any> | null {
const newStoredToken = this.tokenStoreService.getRawAuthToken(AuthTokenType.AccessToken);
const requestAccessTokenHeader = request.headers.get(this.authorizationHeader);
if (!newStoredToken || !requestAccessTokenHeader) {
console.log(" first =>There is no new AccessToken.", { requestAccessTokenHeader: requestAccessTokenHeader, newStoredToken: newStoredToken });
return null;
}
const newAccessTokenHeader = `Bearer ${newStoredToken}`;
if (requestAccessTokenHeader === newAccessTokenHeader) {
console.log(" second =>There is no new AccessToken.", { requestAccessTokenHeader: requestAccessTokenHeader, newAccessTokenHeader: newAccessTokenHeader });
return null;
}
console.log("third")
return request.clone({ headers: request.headers.set(this.authorizationHeader, newAccessTokenHeader) });
}
}
и добавляю это в appmodule:
{ provide: HTTP_INTERCEPTORS,useClass: AuthInterceptorService,multi: true},
и этот запрос:
public UserInfo(username:string):Observable<IUser>{
return this.http.get<IUser>(`${this.baseUrl+'GetUserInfo/'}${username}`,{headers:{
'Content-Type': 'application/json; charset=utf-8'
},
})
.pipe(
tap((user: IUser) => this.log(`GetUserInfo user w/ email=${user}`)),
catchError(this.handleError<IUser>('GetUserInfo user'))
);
}
но это показывает мне эту ошибку:
second => Нет нового AccessToken.Объект {requestAccessTokenHeader: "Канал \" \\ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..NNKPkwayicwLo8K-K1weP7vGAkL8Cpo9Zx-xtrh6I4E \\" \ "", newAccessTokenHeader: "Канал \" \\ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..NNKPkwayicwLo8K-K1weP7vGAkL8Cpo9Zx-xtrh6I4E \\" \ ""}auth-interceptor.service.ts: 74: 6 Object {headers: {…}, status: 401, statusText: «Unauthorized», url: «https://localhost:44390/api/user/GetUserInfo/kia@kia.com", ok: false, name:« HttpErrorResponse », сообщение:«Http-сообщение об ошибке для https://localhost:44390/api/user/GetUserInfo/kia@kia.com: 401 Unauthorized», ошибка: null} user.service.ts: 113: 6 Сбой пользователя GetUserInfo: Http-сообщение об ошибке для https://localhost:44390/api/user/GetUserInfo/kia@kia.com: 401 Unauthorized