我有一个带有ResourceOwnerPasswordAndClientCredentials流的Identity Server和API应用程序。
从RequestResourceOwnerPasswordAsync方法获得“ access_token”后,我可以在我的API项目中使用我的[已授权]端点,但是无法在我的Identity Server应用程序中访问[已授权]端点。
我可能在AllowedScopes中缺少什么吗?
身份服务器的Starup.cs:
public class Startup
{
public Startup(IHostingEnvironment env, ILoggerFactory loggerFactory)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
builder.AddEnvironmentVariables();
Configuration = builder.Build();
var section = Configuration.GetSection("Logging");
loggerFactory.AddConsole(section);
loggerFactory.AddDebug();
loggerFactory.AddProvider(new FileLoggerProvider());
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<IdentityDataContext>(optionsAction =>
optionsAction.UseSqlServer(Configuration.GetConnectionString("DevelopersConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<IdentityDataContext>()
.AddDefaultTokenProviders();
services.AddMvc();
services.AddIdentityServer()
.AddDeveloperSigningCredential(filename: "tempkey.rsa")
.AddInMemoryClients(IdentityConfig.GetClients("http://localhost:7017"))
.AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources())
.AddInMemoryApiResources(IdentityConfig.GetApiResources())
.AddAspNetIdentity<ApplicationUser>();
services.AddCors();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
RolesData.SeedRoles(app).Wait();
app.UseCors(x =>
x.WithOrigins("http://localhost:7017")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
);
app.UseStaticFiles();
app.UseIdentityServer();
app.UseMvc();
}
}
Web Api Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient(typeof(IDataRepository<>), typeof(DataRepository<>));
services.AddDbContext<DataContext>(optionsAction =>
optionsAction.UseSqlServer(Configuration.GetConnectionString("DevelopersConnection")));
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddAuthentication(
JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:7777"; // Auth Server
options.RequireHttpsMetadata = false; // only for development
options.ApiName = "api"; // API Resource Id
options.SupportedTokens = SupportedTokens.Jwt;
});
services.AddCors();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(x =>
x.WithOrigins("http://localhost:7017")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
);
app.UseAuthentication();
app.UseMvc();
}
}
IdentityConfig.cs:
public class IdentityConfig
{
public static IEnumerable<Client> GetClients(string hostname) => new List<Client>
{
new Client
{
ClientId = "client",
ClientName = "application",
AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
AccessTokenType = AccessTokenType.Jwt,
AllowAccessTokensViaBrowser = true,
ClientSecrets = {new Secret("secret".Sha256())},
RequireConsent = false,
RedirectUris = { $"{hostname}/callback.html" },
PostLogoutRedirectUris = { $"{hostname}/index.html" },
AllowedCorsOrigins = { hostname },
AlwaysIncludeUserClaimsInIdToken = true,
AllowOfflineAccess = true,
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OfflineAccess,
JwtClaimTypes.Role,
"api"
}
},
};
public static IEnumerable<IdentityResource> GetIdentityResources() => new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Email(),
new IdentityResources.Profile(),
new IdentityResource("role", new []{ JwtClaimTypes.Role })
};
public static IEnumerable<ApiResource> GetApiResources() => new List<ApiResource>
{
new ApiResource("api")
{
UserClaims =
{
JwtClaimTypes.Email,
JwtClaimTypes.Role,
JwtClaimTypes.IdentityProvider,
IdentityServerConstants.StandardScopes.OpenId
}
}
};
}
获取Jwt access_token:
var disco = await DiscoveryClient.GetAsync("http://localhost:7777");
var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");
var tokenResponse =
await tokenClient.RequestResourceOwnerPasswordAsync("username", "password", "openid api");
var access_token = tokenResponse.AccessToken;