2017-01-30 2 views
1

Я создаю авторизацию/аутентификацию Приложение Angular2 с ASP.NET Core.
Когда я назвал метод с авторизовать атрибут я получаю сообщение об ошибке в окне визуального вывода Студия:OpenIddict с Angular2-jwt

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:50373/api/tasks/GetLatest/ text/plain 
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: Failed to validate the token eyJhbGciOiJSUzI1NiIsImtpZCI6IlJHRUVHM0FCSUJNVllHTEdQSjFSNjNRRkdHQlVKRUlHLU9ITy1QREgiLCJ0eXAiOiJKV1QifQ.eyJ1bmlxdWVfbmFtZSI6Im1hdGphei5jb2ZAb3BhbC5zaSIsIkFzcE5ldC5JZGVudGl0eS5TZWN1cml0eVN0YW1wIjoiMWVhYWE4MzktNzZlNy00NmVhLWE2NGUtYWJmNDVhNzY5YTBiIiwicm9sZSI6IkFkbWluaXN0cmF0b3JzIiwianRpIjoiM2U1NjAyMjUtMzQyNy00YmE4LTg4MzQtYzA2ZGI4NDE2NDA0IiwidXNhZ2UiOiJhY2Nlc3NfdG9rZW4iLCJzY29wZSI6WyJvcGVuaWQiLCJvZmZsaW5lX2FjY2VzcyJdLCJzdWIiOiIxIiwibmJmIjoxNDg1NzgyOTAwLCJleHAiOjE0ODU3ODQ3MDAsImlhdCI6MTQ4NTc4MjkwMCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDM3My8ifQ.IqDnWJJKRtAh0BWKcdQgg_Gm_rnarffdnq5ksqpm0m6BnslI0EZ-7CugSG0223k6_FwuU7iSCiI2Cu7O2uaUedDEOdoIwyxpaEyr6yjzT5pxw7hbMnNxmxAydEajqE3OI-C55vzK0nhv9ToS93dz_QF8MIQ5EMIJ1cGXXO9wqQQ0xLvX7o2wIlM3rYvh_OORdALBxl5byMsrtc3ZrVj-BEiYuuwrUwSU5oPlH28o_Oo030s9NGqaQNea5T3PNQAL8-qC6aIdcDLBwOYZevTGGLMxde9czk_Duc0mkp5KtsyVZ-oV3qTh-EdZxpPjttu5_5Bh-8YCDLP5AzOsyX5sbg. 

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10208: Unable to validate audience. validationParameters.ValidAudience is null or whitespace and validationParameters.ValidAudiences is null. 
    at Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) 
    at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwt, TokenValidationParameters validationParameters) 
    at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) 
    at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__1.MoveNext() 
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: Bearer was not authenticated. Failure message: IDX10208: Unable to validate audience. validationParameters.ValidAudience is null or whitespace and validationParameters.ValidAudiences is null. 
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed for user: (null). 

До этого я войти в себя и получить следующий объект в Angular2 приложение:

access_token:"eyJhbGciOiJSUzI1NiIsImtpZCI6IlJHRUVHM0FCSUJNVllHTEdQSjFSNjNRRkdHQlVKRUlHLU9ITy1QREgiLCJ0eXAiOiJKV1QifQ.eyJ1bmlxdWVfbmFtZSI6Im1hdGphei5jb2ZAb3BhbC5zaSIsIkFzcE5ldC5JZGVudGl0eS5TZWN1cml0eVN0YW1wIjoiMWVhYWE4MzktNzZlNy00NmVhLWE2NGUtYWJmNDVhNzY5YTBiIiwicm9sZSI6IkFkbWluaXN0cmF0b3JzIiwianRpIjoiM2U1NjAyMjUtMzQyNy00YmE4LTg4MzQtYzA2ZGI4NDE2NDA0IiwidXNhZ2UiOiJhY2Nlc3NfdG9rZW4iLCJzY29wZSI6WyJvcGVuaWQiLCJvZmZsaW5lX2FjY2VzcyJdLCJzdWIiOiIxIiwibmJmIjoxNDg1NzgyOTAwLCJleHAiOjE0ODU3ODQ3MDAsImlhdCI6MTQ4NTc4MjkwMCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDM3My8ifQ.IqDnWJJKRtAh0BWKcdQgg_Gm_rnarffdnq5ksqpm0m6BnslI0EZ-7CugSG0223k6_FwuU7iSCiI2Cu7O2uaUedDEOdoIwyxpaEyr6yjzT5pxw7hbMnNxmxAydEajqE3OI-C55vzK0nhv9ToS93dz_QF8MIQ5EMIJ1cGXXO9wqQQ0xLvX7o2wIlM3rYvh_OORdALBxl5byMsrtc3ZrVj-BEiYuuwrUwSU5oPlH28o_Oo030s9NGqaQNea5T3PNQAL8-qC6aIdcDLBwOYZevTGGLMxde9czk_Duc0mkp5KtsyVZ-oV3qTh-EdZxpPjttu5_5Bh-8YCDLP5AzOsyX5sbg" 
expiration_date:"1485784700807" 
expires_in:1800 
id_token:"eyJhbGciOiJSUzI1NiIsImtpZCI6IlJHRUVHM0FCSUJNVllHTEdQSjFSNjNRRkdHQlVKRUlHLU9ITy1QREgiLCJ0eXAiOiJKV1QifQ.eyJ1bmlxdWVfbmFtZSI6Im1hdGphei5jb2ZAb3BhbC5zaSIsIkFzcE5ldC5JZGVudGl0eS5TZWN1cml0eVN0YW1wIjoiMWVhYWE4MzktNzZlNy00NmVhLWE2NGUtYWJmNDVhNzY5YTBiIiwicm9sZSI6IkFkbWluaXN0cmF0b3JzIiwic3ViIjoiMSIsImp0aSI6IjFmMTAzODI1LTAyM2ItNDAwNy05NjI3LTI4ODk0MmZmNzM5NyIsInVzYWdlIjoiaWRlbnRpdHlfdG9rZW4iLCJhdF9oYXNoIjoiRGVXaUcwbklJWXVxcW9vUVlBclQ3USIsIm5iZiI6MTQ4NTc4MjkwMCwiZXhwIjoxNDg1Nzg0MTAwLCJpYXQiOjE0ODU3ODI5MDAsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTAzNzMvIn0.WDvRzyG63Ok9ZjgbACzwSDsgA1mxndtx8klY64sPg3a_oeQE-rtd0EMyYnzp4uLTDW8uU6MEzuyZeufBE5SaRXMiXH45raH468XkPvX6qbSUjV2ZV6rER36eI_gFnnnGSQzfz0vSZE1Uq8-fCxxaGpjHLrNRuDWb7o--4t4mGfI6-MOvEY46IO6pgnD9GV9BTv-SzRjuQh7BTGvKu2ITkQVqbGiwLlHN-ilu2l8HG3vB0ewePcK_mvCkhbUz8n9R6q5BHrQm2qUXGMjHE023JBb6LPr3kS_9zGKgEhWRmMkclkNiQgHtFBjMxK2jG-8v14MLaVJx4fGS4q08OqQJjg" 
refresh_token:"CfDJ8EUVTnABx9VCmidQlFBiYKJ1b8N1-ggRbkY6PYVT6xwuO-xG8KL64rVld2UhXTnirKU06W2bhPPE3MU42SOji3p69aZH-VYuQQwZzXyJE3AqCh-uFQ0_XynvVQn0o15x0ozknKhk3j1N9mIvuzzZ2Lc1L5hXUL1JdhkkOQmQ42JzDSEeDFp0fwCsdAAtXdY1Cvz1Xg-WiHP8Aco4pvkFxh7vioLGcR1xmmEALHEDePj7xrnP7dzwrCe4F9bhFyTx1MW-MW5Q2kVogMwa_yxbTm4kjmO2mbt9tjpeLT_aIkE7R78AqTLw_P5pwd-nxS_rc-U9IusBpOaabdHy6bNKppxzAq-1NQr0oOf2nJMEahcKjNTMo1ip78u05Xxl4btV_f7Pf-auX7bZ1GbaqBhIrwp6Ld2tPI1E-462r-H2ufmFfW50x_5OsFcJDBR5jXolLOfo1yNStqujo0ov6AR1g5hwVaq2luYl5z-iHtgiEvbQCVNzs5anu1qeaJp3oe0GSwZ0Z2SqFu4ewWE9clFxAmH8uFvI3wwsWEXfqHiXOYFQRf4shgA9VLPktGaQd7uafuSzMUrT_xguTaaLlzmq7MM8ODPrV2qblfXTUn3BMsWLp31ZOpg6aUpR4fTDP-LLnVQVi3NTyFuQwc0dUtpYrArI4YcC97lNFTzOgf9aHXKA8_4oBaCmXQsM-39A3ynDDfV4SSmhViKUOJ7KMmb4f-Og5cckldgbgcKEXd7tSJmZOsiu5rKymKHHIU4v94_5WK3dVwDfG-pb8vg1HQP_b06lIPYNYGve80CHLMLs2V_56pwN0sRa327DY6q5rLFRZ7An8jr7Bdc94EJLYEW-gtQf29NCM5sMwlqV9xlj3ZeR-r2fBdpVsT8IjlJD5qe6KnCY6jYQAgoDagfkIy4GjBGuJmR8L4IHrsSkzJAA6nVw" 
token_type:"Bearer" 

и мой файл запуска :

public void ConfigureServices(IServiceCollection services) 
{ 
    try 
    { 
     services.AddMvc(); 

     services.AddEntityFrameworkSqlServer(); 

     services.AddScoped<UserStore<AppUser, AppRole, AppDbContext, int, AppUserClaim, AppUserRole, AppUserLogin, AppUserToken, AppRoleClaim>, AppUserStore>(); 
     services.AddScoped<UserManager<AppUser>, AppUserManager>(); 
     services.AddScoped<RoleManager<AppRole>, AppRoleManager>(); 
     services.AddScoped<SignInManager<AppUser>, AppSignInManager>(); 
     services.AddScoped<RoleStore<AppRole, AppDbContext, int, AppUserRole, AppRoleClaim>, AppRoleStore>(); 

     var connection = Configuration["ConnectionStrings"]; 
     services.AddDbContext<AppDbContext>(options => { 
      options.UseSqlServer(connection); 
      options.UseOpenIddict<int>(); 
     }); 

     services 
      .AddIdentity<AppUser, AppRole>() 
      .AddUserStore<AppUserStore>() 
      .AddUserManager<AppUserManager>() 
      .AddRoleStore<AppRoleStore>() 
      .AddRoleManager<AppRoleManager>() 
      .AddSignInManager<AppSignInManager>() 
      .AddDefaultTokenProviders(); 

     services.AddOpenIddict<int>() 
      .AddEntityFrameworkCoreStores<AppDbContext>() 
      .AddMvcBinders() 
      .EnableTokenEndpoint("/API/authorization/token") 
      .AllowPasswordFlow() 
      .AllowRefreshTokenFlow() 
      .UseJsonWebTokens() 
      .AddEphemeralSigningKey()  //todo naj bi bil pravi certifikat, če odstranič to vrstico ne dela in vidiš error. 
      .DisableHttpsRequirement(); 

     services.AddSingleton<DbSeeder>(); 

    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.ToString()); 
     throw; 
    } 
} 

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, DbSeeder dbSeeder) 
{ 
    loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
    loggerFactory.AddDebug(); 

    if (env.IsDevelopment()) 
    { 
     app.UseDeveloperExceptionPage(); 
     app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions 
     { 
      HotModuleReplacement = true 
     }); 
    } 
    else 
    { 

    } 

    app.UseStaticFiles(); 

    app.UseIdentity(); 

    app.UseOpenIddict(); 

    //app.UseOAuthValidation();  //this works 
    app.UseJwtBearerAuthentication(new JwtBearerOptions() 
    {     
     Authority = "http://localhost:50373/", 
     AutomaticAuthenticate = true, 
     AutomaticChallenge = true, 
     RequireHttpsMetadata = false 
    }); 

    app.UseMvc(); 

    try 
    { 

     dbSeeder.SeedAsync(); 
    } 
    catch (AggregateException e) 
    { 
     throw new Exception(e.ToString()); 
    } 
} 

}

Консоль разработчика Контейнеры в закладке Сеть:

Request URL:http://localhost:50373/api/tasks/GetLatest/ 
Request Method:GET 
Status Code:302 Found 
Remote Address:[::1]:50373 
Response Headers 
view source 
Content-Length:0 
Date:Mon, 30 Jan 2017 13:32:28 GMT 
Location:http://localhost:50373/Account/Login?ReturnUrl=%2Fapi%2Ftasks%2FGetLatest%2F 
Server:Kestrel 
WWW-Authenticate:Bearer error="invalid_token", error_description="The audience is invalid" 
X-Powered-By:ASP.NET 
X-SourceFiles:=?UTF-8?B?RDpcT3BQSVNXZWJcdHJ1bmtcT3BQSVNXZWJcYXBpXHRhc2tzXEdldExhdGVzdFw=?= 
Request Headers 
view source 
Accept:*/* 
Accept-Encoding:gzip, deflate, sdch, br 
Accept-Language:sl-SI,sl;q=0.8,en-GB;q=0.6,en;q=0.4 
authorization:Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IlJHRUVHM0FCSUJNVllHTEdQSjFSNjNRRkdHQlVKRUlHLU9ITy1QREgiLCJ0eXAiOiJKV1QifQ.eyJ1bmlxdWVfbmFtZSI6Im1hdGphei5jb2ZAb3BhbC5zaSIsIkFzcE5ldC5JZGVudGl0eS5TZWN1cml0eVN0YW1wIjoiMWVhYWE4MzktNzZlNy00NmVhLWE2NGUtYWJmNDVhNzY5YTBiIiwicm9sZSI6IkFkbWluaXN0cmF0b3JzIiwianRpIjoiM2U1NjAyMjUtMzQyNy00YmE4LTg4MzQtYzA2ZGI4NDE2NDA0IiwidXNhZ2UiOiJhY2Nlc3NfdG9rZW4iLCJzY29wZSI6WyJvcGVuaWQiLCJvZmZsaW5lX2FjY2VzcyJdLCJzdWIiOiIxIiwibmJmIjoxNDg1NzgyOTAwLCJleHAiOjE0ODU3ODQ3MDAsImlhdCI6MTQ4NTc4MjkwMCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDM3My8ifQ.IqDnWJJKRtAh0BWKcdQgg_Gm_rnarffdnq5ksqpm0m6BnslI0EZ-7CugSG0223k6_FwuU7iSCiI2Cu7O2uaUedDEOdoIwyxpaEyr6yjzT5pxw7hbMnNxmxAydEajqE3OI-C55vzK0nhv9ToS93dz_QF8MIQ5EMIJ1cGXXO9wqQQ0xLvX7o2wIlM3rYvh_OORdALBxl5byMsrtc3ZrVj-BEiYuuwrUwSU5oPlH28o_Oo030s9NGqaQNea5T3PNQAL8-qC6aIdcDLBwOYZevTGGLMxde9czk_Duc0mkp5KtsyVZ-oV3qTh-EdZxpPjttu5_5Bh-8YCDLP5AzOsyX5sbg 
Cache-Control:no-cache 
Connection:keep-alive 
content-type:text/plain 
Host:localhost:50373 
Pragma:no-cache 
Referer:http://localhost:50373/tasks 
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 

Что я пропустил?

Обновлено:

Как я уже говорил в комментариях не забудьте сохранить access_token в id_token локального хранилища:

private login(username: string, password: string) 
    { 
     let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' }); 
     let options = new RequestOptions({ headers: headers }); 

     const data = { username: username, password: password }; 
     Object.assign(data, { 
      grant_type: "password", 
      // offline_access is required for a refresh token 
      scope: ['openid offline_access'] 
     }); 

     return this.http.post('api/authorization/token', this.encodeObjectToParams(data), options) 
      .map(res => res.json()) 
      .map((tokens: AuthTokenModel) => 
      { 
       localStorage.setItem('id_token', tokens.access_token); //!!! 

       return tokens; 
      }); 
    } 

потому Angular2-jwt использование id_token для маркеров доступа по умолчанию.

ответ

1

Как указано, за исключением, вы должны установить Audience свойство:

app.UseJwtBearerAuthentication(new JwtBearerOptions 
{     
    Authority = "http://localhost:50373/", 
    Audience = "resource_server", 
    AutomaticAuthenticate = true, 
    AutomaticChallenge = true, 
    RequireHttpsMetadata = false 
}); 

Вы также должны установить ресурс в билете аутентификации:

ticket.SetResources("resource_server"); 
+0

angular2-JWT по умолчанию выглядит для элемента id_token в локальном хранилище. OpenIddict возвращает объект, имеющий свойство id_token и access_token. Обязательно сохраните access_token в локальном хранилище как id_token. – Makla

Смежные вопросы