.net 4.6 web api2 401 未经授权使用身份服务器 4
Posted
技术标签:
【中文标题】.net 4.6 web api2 401 未经授权使用身份服务器 4【英文标题】:.net 4.6 web api2 401 Unauthorized with identity server 4 【发布时间】:2020-08-11 01:13:29 【问题描述】:我已经在 .net 核心应用程序中有一个工作身份服务器 4。
namespace IdentityServer
public class Config
public static IEnumerable<ApiResource> GetApiResources()
return new List<ApiResource>
new ApiResource("myresourceapi", "My Resource API")
Scopes = new Scope("apiscope")
;
public static IEnumerable<Client> GetClients()
return new[]
// for public api
new Client
ClientId = "secret_client_id",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
new Secret("secret".Sha256())
,
AllowedScopes = "apiscope"
;
namespace IdentityServer
public class Startup
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddOperationalStore(options =>
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30; // interval in seconds
)
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseIdentityServer();
app.UseRouting();
app.UseEndpoints(endpoints =>
endpoints.MapGet("/", async context =>
await context.Response.WriteAsync("Hello World!");
);
);
问题是现在我需要向 .net 4.6 web api2(不是核心)发出经过身份验证的请求。而 IdentityServer4.AccessTokenValidation 包对此不起作用。
根据这个问题(https://***.com/questions/41992272/is-it-possible-to-use-identity-server-4-running-on-net-core-with-a-webapi-app-r
),我所要做的就是使用与身份服务器 3(IdentityServer3.AccessTokenValidation)相同的包。
这是我在 webapi 2 中实现的代码
using IdentityServer3.AccessTokenValidation;
using Microsoft.Owin;
using Owin;
using Microsoft.Owin.Host.SystemWeb;
using IdentityModel.Extensions;
using System.Web.Http;
[assembly: OwinStartup(typeof(WebApplication10.Startup))]
namespace WebApplication10
public partial class Startup
public void Configuration(IAppBuilder app)
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
Authority = "https://localhost:44357",
// For access to the introspection endpoint
ClientId = "secret_client_id",
ClientSecret = "secret".ToSha256(),
RequiredScopes = new[] "apiscope"
);
namespace WebApplication10.Controllers
public class ValuesController : ApiController
[Authorize]
// GET api/values
public IEnumerable<string> Get()
return new string[] "value1", "value2" ;
我一直得到的状态是 401 Unauthorized。 难道我做错了什么? 有什么帮助吗? 谢谢。
【问题讨论】:
您检查了 identityserver4 日志吗?它们非常冗长,将指导您找到问题的正确解决方案。 identityserver4.readthedocs.io/en/latest/topics/logging.html. 【参考方案1】:如果没有日志,无法确定您的情况是什么问题,但我做了一些修复以使其正常工作:
-
在 IdentityServer 项目的
Statup.cs
类上
将AccessTokenJwtType
更改为JWT
,IdentityServer4 上的默认值为at+jwt
,但.Net Framework Api (OWIN/Katana) 需要JWT
。
通过将EmitLegacyResourceAudienceClaim
设置为true 添加/resources
aud,这在IdentityServer4 上被删除。
您可以通过检查"typ"
和"aud"
来验证https://jwt.ms/ 上的access_token。
var builder = services.AddIdentityServer(
options =>
options.AccessTokenJwtType = "JWT";
options.EmitLegacyResourceAudienceClaim = true;
);
-
在.Net Framework Api 项目的
Statup.cs
类上,将ValidationMode
设置为ValidationMode.Local
,此方法使用的自定义访问令牌验证端点已在IdentityServer4 上移除。
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
Authority = "https://localhost:44357",
// For access to the introspection endpoint
ClientId = "secret_client_id",
ClientSecret = "secret".ToSha256(),
RequiredScopes = new[] "apiscope" ,
ValidationMode = ValidationMode.Local,
);
我有示例工作实现here
我强烈建议您收集有关 API 的日志,这有助于在您的案例中找到实际问题并找到解决方法。 here是开启OWIN登录Api的样例。
【讨论】:
【参考方案2】:您可以关注CrossVersionIntegrationTests 的示例。
身份服务器 4 没有 connect/accesstokenvalidation
端点。所以在身份 server4 应用程序中,您可以修改您的 ApiResource
以添加 ApiSecret
:
new ApiResource("api1", "My API") ApiSecrets = new List<Secret> new Secret("scopeSecret".Sha256())
然后在您的网络 api 中,配置 IdentityServerBearerTokenAuthenticationOptions
之类的:
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
Authority = "http://localhost:5000",
ValidationMode = ValidationMode.ValidationEndpoint,
ClientId = "api1",
ClientSecret = "scopeSecret",
RequiredScopes = new[] "api1"
);
ClientId
& ClientSecret
都来自您的 ApiResource 。
【讨论】:
您好,感谢您的回复,对我有用的方法是编辑 Identity server 4 配置,正如您所说,在 config.cs IEnumerablemyresourceapi
然后使用它以上是关于.net 4.6 web api2 401 未经授权使用身份服务器 4的主要内容,如果未能解决你的问题,请参考以下文章
Angular 6 对 .NET Web API 的跨域 POST 请求返回 401(未经授权)
当用户未经身份验证时,ASP.NET Core 5 Web API 返回 404 代码而不是 401
.NET Core - 在 IIS 上使用 Windows 身份验证从 MVC 应用程序调用 Web API 导致 HttpRequestException 401(未经授权)状态代码
Angular MSAL AD 401 在 Angular 应用程序中未经授权,但在 Postman 中 200 正常 - ASP.NET Core Web API