2017-05-19 39 views
13

我一直在努力移植一個單一的ASP核心MVC應用程序來使用服務架構設計。 MVC前端網站使用HttpClient從ASP Core Web API加載必要的數據。前端MVC應用程序的一小部分還要求使用IdentityServer4(與後端API集成)進行身份驗證。這一切都很好,直到我將一個Authorize屬性放在Web API上的控制器或方法上。我知道我需要以某種方式將用戶授權從前端傳遞到後端才能實現,但我不知道如何。我嘗試過獲取access_token:User.FindFirst("access_token"),但它返回null。那麼這個方法我試過,我能夠獲得令牌:通過與ASP核心MVC,Web API和IdentityServer4認證?

var client = new HttpClient("url.com"); 
var token = HttpContext.Authentication.GetTokenAsync("access_token")?.Result; 
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); 

這種方法得到令牌,但仍無法與後端API認證。我對這個OpenId/IdentityServer概念相當陌生,希望有任何幫助。

下面是從MVC客戶端啓動類的相關代碼:

private void ConfigureAuthentication(IApplicationBuilder app) 
    { 
     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationScheme = "Cookies", 
      AutomaticAuthenticate = true, 
      ExpireTimeSpan = TimeSpan.FromMinutes(60) 
     }); 
     JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); 
     app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions 
     { 
      AuthenticationScheme = "oidc", 
      SignInScheme = "Cookies", 

      Authority = "https://localhost:44348/", 
      RequireHttpsMetadata = false, 

      ClientId = "clientid", 
      ClientSecret = "secret", 

      ResponseType = "code id_token", 
      Scope = { "openid", "profile" }, 
      GetClaimsFromUserInfoEndpoint = true, 
      AutomaticChallenge = true, // Required to 302 redirect to login 
      SaveTokens = true, 

      TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters 
      { 
       NameClaimType = "Name", 
       RoleClaimType = "Role", 
       SaveSigninToken = true 
      }, 


     }); 
    } 

,並啓動類的API:

 // Add authentication 
     services.AddIdentity<ExtranetUser, IdentityRole>(options => 
     { 
      // Password settings 
      options.Password.RequireDigit = true; 
      options.Password.RequiredLength = 8; 
      options.Password.RequireNonAlphanumeric = true; 
      options.Password.RequireUppercase = true; 
      options.Password.RequireLowercase = true; 

      // Lockout settings 
      options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); 
      options.Lockout.MaxFailedAccessAttempts = 10; 

      // User settings 
      options.User.RequireUniqueEmail = true; 
     }) 
      .AddDefaultTokenProviders(); 
     services.AddScoped<IUserStore<ExtranetUser>, ExtranetUserStore>(); 
     services.AddScoped<IRoleStore<IdentityRole>, ExtranetRoleStore>(); 
     services.AddSingleton<IAuthorizationHandler, AllRolesRequirement.Handler>(); 
     services.AddSingleton<IAuthorizationHandler, OneRoleRequirement.Handler>(); 
     services.AddSingleton<IAuthorizationHandler, EditQuestionAuthorizationHandler>(); 
     services.AddSingleton<IAuthorizationHandler, EditExamAuthorizationHandler>(); 
     services.AddAuthorization(options => 
     { 
      /* ... etc .... */ 
     }); 
     var serviceProvider = services.BuildServiceProvider(); 
     var serviceSettings = serviceProvider.GetService<IOptions<ServiceSettings>>().Value; 
     services.AddIdentityServer() // Configures OAuth/IdentityServer framework 
      .AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources()) 
      .AddInMemoryClients(IdentityServerConfig.GetClients(serviceSettings)) 
      .AddAspNetIdentity<ExtranetUser>() 
      .AddTemporarySigningCredential(); // ToDo: Add permanent SigningCredential for IdentityServer 

回答

2

添加了nuget package here和下面的代碼來解決:

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions 
{ 
    Authority = "https://localhost:44348/", 
    ApiName = "api" 
}); 

這允許API承載IdentityServer4並將其自身用作驗證tication。然後在MvcClient中,不記名令牌可以傳遞給API。

0

是的,您需要將IdentityServer4.AccessTokenValidation包添加到您的API項目。並檢查以下

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions 
{ 
    Authority = "https://localhost:44348/", //Identity server host uri 
    ApiName = "api", // Valid Api resource name 
    AllowedScopes = scopes // scopes:List<string> 
}); 

的意見,您應該刪除從啓動類的API和下面的代碼替換上述一個:

services.AddIdentityServer() // Configures OAuth/IdentityServer framework 
      .AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources()) 
      .AddInMemoryClients(IdentityServerConfig.GetClients(serviceSettings)) 
      .AddAspNetIdentity<ExtranetUser>() 
      .AddTemporarySigningCredential(); 

需要在上面的代碼你身份服務器不在API或任何其他客戶端上