我遇到了一個問題,包括在與AspNet Core Identity集成成功登錄到Identity Server 4(IS4)後的角色聲明。這使我無法使用「授權(角色= xxx)」屬性來保護對api的訪問。在Identity Server 4中包含Core Identity角色聲明id_token
我正在關注Identity Server 4/AspNet Identity集成文檔中提供的示例。令人驚訝的是,文檔沒有一個例子來包含角色聲明,我認爲這是一種非常常見的情況。
我按照IS4文檔設置了3個項目,並在主機中指定了HybridClientCredential授權類型,創建了AspNet Identity DB,並將角色(「Admin」)手動添加到由EF Core生成的數據庫中。假如我已經正確設置了一些東西,我預計在成功登錄後,角色會自動包含在用戶聲明中。
- ASPNET核心(個人認證)/標識服務器(主機)
- MVC應用程序(客戶端)
- MVC的Web API(API)
這是我使用的代碼:
主持人:
public class Config
{
public static IEnumerable<ApiResource> GetApiResources()
{
return new[]
{
// expanded version if more control is needed
new ApiResource
{
Name = "api1",
Description = "My API",
// secret for using introspection endpoint
ApiSecrets =
{
new Secret("secret".Sha256())
},
// include the following using claims in access token (in addition to subject id)
UserClaims = { "role" },
// this API defines two scopes
Scopes =
{
new Scope()
{
Name = "api1",
DisplayName = "Full access to API 1",
UserClaims = new [] { "role" }
}
}
}
};
}
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>()
{
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = false,
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = { "http://localhost:5002/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AlwaysIncludeUserClaimsInIdToken = true,
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
},
AllowOfflineAccess = true
}
};
}
}
客戶:
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies"
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ClientId = "mvc",
ClientSecret = "secret",
ResponseType = "code id_token",
Scope = { "api1", "offline_access" },
GetClaimsFromUserInfoEndpoint = true,
SaveTokens = true,
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role,
}
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
API:
[Route("api/[controller]")]
[Authorize(Roles="Admin")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
// POST api/values
[HttpPost]
public void Post([FromBody]string value)
{
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
我的設置除了主機不包括成功登錄後,角色要求的工作。
我想知道是否有人可以幫助讓我知道如何解決這個問題?謝謝。