我有一个带有ResourceOwnerPasswordAndClientCredentials流的Identity Server和API应用程序 .

从RequestResourceOwnerPasswordAsync方法获取“access_token”后,我可以在我的API项目中使用我的[授权] endpoints ,但无法访问我的Identity Server应用程序中的[授权] endpoints .

可能是我在AllowedScopes中遗漏了什么?

Identity Server的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;