Identity Server 4 使用有效访问令牌获取 401 .net Core 3.1
Identity Server 4 Getting 401 with valid access token .net Core 3.1
我在我的 .NET Core 3.1 API 应用程序中使用身份服务器 4。我在本地服务器上获得成功令牌 https://localhost:[port]/connect/token 并且当我使用不记名令牌访问授权方法时,我总是收到 401 错误。
我只有 1 个添加了 [授权] 的控制器。
这是我的 startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddCookiePolicy();
services.AddIdentity<AppUser, IdentityRole>(identityOptions =>
{
identityOptions.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
identityOptions.Lockout.MaxFailedAccessAttempts = 6;
identityOptions.Password.RequiredLength = 8;
})
.AddUserManager<CustomUserManager>()
.AddUserStore<CustomUserStorage>()
.AddEntityFrameworkStores<AppIdentityDbContext>()
.AddSignInManager<CustomSignInManager>()
.AddErrorDescriber<CustomIdentityErrorDescriber>();
services.ConfigureApplicationCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
};
});
var sqlConnectionString = Configuration.GetConnectionString("SqlServer");
var migrationsAssembly = typeof(AppUser).GetTypeInfo().Assembly.GetName().Name;
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApis())
.AddInMemoryClients(Config.GetClients())
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(sqlConnectionString, db => MigrationAndRetryBuilder(db, migrationsAssembly));
options.DefaultSchema = AppIdentityDbContext.Schema;
})
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(sqlConnectionString, db => MigrationAndRetryBuilder(db, migrationsAssembly));
options.DefaultSchema = AppIdentityDbContext.Schema;
});
services.AddControllers();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = Configuration["Authentication:Authorization"];
options.RequireHttpsMetadata = false;
options.Audience = "ap1";
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, IdentityServerDatabaseInitialization databaseInitialization)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// app.UseDatabaseErrorPage();
}
else
{
app.UseHsts();
}
if (Configuration.GetValue<bool>("UseSecureHeaders", false))
{
ConfigureAppSecureHeaders(app);
}
var pathBase = Configuration["PATH_BASE"];
if (!string.IsNullOrEmpty(pathBase))
{
loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase);
app.UsePathBase(pathBase);
}
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("AllowAll");
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
这是我的 config.cs:
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email(),
new IdentityResources.Address(),
new IdentityResources.Phone()
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("ap1","My Api")
{
Description="Api with Bearer Token",
Scopes= new []{ new Scope("ap1"), new Scope("offline_access"),new Scope(IdentityServerConstants.LocalApi.ScopeName) },
ApiSecrets= new []{ new Secret("secret".Sha256()) }
}
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
RequireConsent=false,
ClientId = "ap1",
ClientName="My Api",
AllowOfflineAccess=true,
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ClientCredentials,
// scopes that client has access to
AllowedScopes = { "ap1", "offline_access", IdentityServerConstants.LocalApi.ScopeName },
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
}
};
}
解决方案
最后我决定将 IdentityServer 分离到它自己的服务中,现在一切都在使用简单的配置
最后我决定将 IdentityServer 分离到它自己的服务中,现在一切都在使用简单的配置
我在我的 .NET Core 3.1 API 应用程序中使用身份服务器 4。我在本地服务器上获得成功令牌 https://localhost:[port]/connect/token 并且当我使用不记名令牌访问授权方法时,我总是收到 401 错误。
我只有 1 个添加了 [授权] 的控制器。
这是我的 startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddCookiePolicy();
services.AddIdentity<AppUser, IdentityRole>(identityOptions =>
{
identityOptions.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
identityOptions.Lockout.MaxFailedAccessAttempts = 6;
identityOptions.Password.RequiredLength = 8;
})
.AddUserManager<CustomUserManager>()
.AddUserStore<CustomUserStorage>()
.AddEntityFrameworkStores<AppIdentityDbContext>()
.AddSignInManager<CustomSignInManager>()
.AddErrorDescriber<CustomIdentityErrorDescriber>();
services.ConfigureApplicationCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
};
});
var sqlConnectionString = Configuration.GetConnectionString("SqlServer");
var migrationsAssembly = typeof(AppUser).GetTypeInfo().Assembly.GetName().Name;
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApis())
.AddInMemoryClients(Config.GetClients())
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(sqlConnectionString, db => MigrationAndRetryBuilder(db, migrationsAssembly));
options.DefaultSchema = AppIdentityDbContext.Schema;
})
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(sqlConnectionString, db => MigrationAndRetryBuilder(db, migrationsAssembly));
options.DefaultSchema = AppIdentityDbContext.Schema;
});
services.AddControllers();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = Configuration["Authentication:Authorization"];
options.RequireHttpsMetadata = false;
options.Audience = "ap1";
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, IdentityServerDatabaseInitialization databaseInitialization)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// app.UseDatabaseErrorPage();
}
else
{
app.UseHsts();
}
if (Configuration.GetValue<bool>("UseSecureHeaders", false))
{
ConfigureAppSecureHeaders(app);
}
var pathBase = Configuration["PATH_BASE"];
if (!string.IsNullOrEmpty(pathBase))
{
loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase);
app.UsePathBase(pathBase);
}
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("AllowAll");
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
这是我的 config.cs:
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email(),
new IdentityResources.Address(),
new IdentityResources.Phone()
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("ap1","My Api")
{
Description="Api with Bearer Token",
Scopes= new []{ new Scope("ap1"), new Scope("offline_access"),new Scope(IdentityServerConstants.LocalApi.ScopeName) },
ApiSecrets= new []{ new Secret("secret".Sha256()) }
}
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
RequireConsent=false,
ClientId = "ap1",
ClientName="My Api",
AllowOfflineAccess=true,
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ClientCredentials,
// scopes that client has access to
AllowedScopes = { "ap1", "offline_access", IdentityServerConstants.LocalApi.ScopeName },
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
}
};
}
解决方案
最后我决定将 IdentityServer 分离到它自己的服务中,现在一切都在使用简单的配置
最后我决定将 IdentityServer 分离到它自己的服务中,现在一切都在使用简单的配置