2016-08-11 41 views
13

這就是我「學習」如何做到這一點的頁面:https://stormpath.com/blog/token-authentication-asp-net-coreRestSharp智威湯遜的身份驗證不起作用

但對我來說這是不工作(不與提琴手工作,太) 有是這個控制器我ApplicationUser模型:

[Authorize] //works when it's not set, doesn't work when it's set 
[Route("api/[controller]")] 
public class ApplicationUserController : Controller 
{ 
    private IRepository<ApplicationUser> _applicationUserRepository; 

    public ApplicationUserController(IRepository<ApplicationUser> applicationUserRepository) 
    { 
     _applicationUserRepository = applicationUserRepository; 
    } 

    [HttpGet("{id}")] 
    public ApplicationUser Get(int id) 
    { 
     return _applicationUserRepository.Get(id); 
    } 
} 

,並有我的包裝的RestSharp讓所有applicationusers:

public Task<T> GetResponseContentAsync<T>(string resource, int id) where T : new() 
{ 
    RestRequest request = new RestRequest($"{resource}/{{id}}", Method.GET); 
    request.AddUrlSegment("id", id); 
    if (!AuthenticationToken.IsNullOrEmpty(true)) 
    { 
     request.AddHeader("Authorization", string.Format("Bearer {0}", AuthenticationToken)); 
     _client.Authenticator = new JwtAuthenticator(AuthenticationToken); 
     _client.Authenticator.Authenticate(_client, request); 
    } 

    TaskCompletionSource<T> tcs = new TaskCompletionSource<T>(); 
    _client.ExecuteAsync<T>(request, response => 
    { 
     tcs.SetResult(response.Data); 
    }); 
    return tcs.Task; 
} 

從Web客戶端APPLI陽離子我想用JWT(令牌認證)登錄什麼工作。登錄後,我得到這個的access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJURVNUIiwianRpIjoiZTBjYjE0NjgtYzBmOS00ZTM4LTg4ZjgtMGM4ZjNmYjMyNjZmIiwiaWF0IjoxNDcwOTUwMTA0LCJuYmYiOjE0NzA5NTAxMDQsImV4cCI6MTQ3MDk1MDQwNCwiaXNzIjoiRXhhbXBsZUlzc3VlciIsImF1ZCI6IkV4YW1wbGVBdWRpZW5jZSJ9.a9_JK2SG3vzc6NSOB0mZXqHlM9UAEXUHHrrijAQUsX0

沒有Authorize -attribute我得到的ApplicationUser,但設置的屬性時,結果爲空(因爲網絡的API是沒有得到所謂的)

包裝呼叫的樣子這個:

//this works, token-value is set 
string token = new RepositoryCall("http://localhost:54008/").Login("token", "TEST", "TEST123"); 

string accessToken = JsonConvert.DeserializeObject<Dictionary<string, string>>(token)["access_token"]; 
ViewData["Result"] = accessToken; 

ApplicationUser userAfterLogin = await new RepositoryCall("http://localhost:54008/api") 
    { AuthenticationToken = accessToken } 
    .GetResponseContentAsync<ApplicationUser>("ApplicationUser", 2); 

and here userAfterLogin is null。

我試圖獲取登錄由於兩個星期,但我仍然沒有得到它的權利..

任何想法,我做錯了嗎?也許是一個錯誤的請求標題值授權?

更新

這是我Startup.Configure,我配置爲使用承載/ JWT:

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

    if (env.IsDevelopment()) 
    { 
     app.UseDeveloperExceptionPage(); 
     app.UseDatabaseErrorPage(); 
     app.UseBrowserLink(); 
    } 
    else 
    { 
     app.UseExceptionHandler("/Home/Error"); 
    } 

    app.UseStaticFiles(); 

    app.UseIdentity(); 
    var secretKey = "mysupersecret_secretkey!123"; 
    var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey)); 

    // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715 
    var options = new TokenProviderOptions 
    { 
     Audience = "ExampleAudience", 
     Issuer = "ExampleIssuer", 
     SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256), 
    }; 


    var tokenValidationParameters = new TokenValidationParameters 
    { 
     // The signing key must match! 
     ValidateIssuerSigningKey = true, 
     IssuerSigningKey = signingKey, 

     // Validate the JWT Issuer (iss) claim 
     ValidateIssuer = true, 
     ValidIssuer = "ExampleIssuer", 

     // Validate the JWT Audience (aud) claim 
     ValidateAudience = true, 
     ValidAudience = "ExampleAudience", 

     // Validate the token expiry 
     ValidateLifetime = true, 

     // If you want to allow a certain amount of clock drift, set that here: 
     ClockSkew = TimeSpan.Zero 
    }; 


    app.UseJwtBearerAuthentication(new JwtBearerOptions 
    { 
     AutomaticAuthenticate = true, 
     AutomaticChallenge = true, 
     TokenValidationParameters = tokenValidationParameters 
    }); 

    app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AutomaticAuthenticate = true, 
     AutomaticChallenge = true, 
     AuthenticationScheme = "Cookie", 
     CookieName = "access_token", 
     TicketDataFormat = new CustomJwtDataFormat(
      SecurityAlgorithms.HmacSha256, 
      tokenValidationParameters) 
    }); 

    app.UseMiddleware<TokenProviderMiddleware>(Options.Create(options)); 
    app.UseMvc(routes => 
    { 
     routes.MapRoute(
      name: "default", 
      template: "{controller=Home}/{action=Index}/{id?}"); 
    }); 
} 
+0

你試過手動調用您的控制器的方法(即使用郵差/小提琴手)? – mateudu

+0

我試過了,但是如何在執行請求時將令牌設置爲fiddler? –

+0

改爲使用郵遞員。這很容易。 – mateudu

回答

0

所以,你正在使用2箇中間件身份。一個由asp.net提供的身份(基於cookie)和另一個基於令牌。現在,這兩個中間件都使用相同的屬性來處理請求[授權] 。更確切地說看看這裏的代碼

https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs

爲JWTBearer

https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs

用於餅乾

因爲兩者都是在中間件管道激活校長將有數據發送授權令牌或cookie時。

但是因爲它們都處於活動狀態,它們中的任何一個都會針對沒有cookie或JwtBearer的請求返回Unauthorized。

對於您正在尋找的解決方案,您需要在現有Cookie和令牌的基礎上創建一箇中間件,以便根據授權標頭是否存在將請求路由到要求。

0

在Fiddler中你會看到,如果你被重定向到登錄頁面(它會報告2個結果,一個用302(重定向),然後是404 - 是這種情況嗎?

你有DebugLogger激活,所以儘量AddDebug(LogLevel.Trace),並查看調試輸出窗口,它是在分析其中的認證步驟失敗非常有幫助。它還會顯示身份驗證是否失敗或授權,以及是否具有有效的令牌等,因此它指向尋找問題的方向。