获取 401 - 调用受 Identity Server 3 保护的 .Net Core 2.2 API 时发生未经授权的错误
Getting 401 - Unauthorized error while calling .Net Core 2.2 API which is secured by Identity Server 3
对于我的移动应用程序,我正在尝试创建一个安全的 API。我使用 ResourceOwner Flow 创建了一个带有身份服务器 3 的 oAuth 服务器。令牌生成成功。但是每当我调用受保护的 API 时,我都会收到 401-unauthorized 错误。
OAuth 服务器的代码下方
`var defaultmobileClient = new Client
{
ClientId = "iqimplicit",
ClientName = "iqimplicit",
Flow = Flows.ResourceOwner,
AllowAccessToAllScopes = true,
IdentityTokenLifetime = 300,//default value is 5 minutes this is the token that allows a user to login should only be used once
AccessTokenLifetime = 3600, // default is one hour access token is used for securing routes and access to api in IQ
RequireConsent = false,
RequireSignOutPrompt = true,
ClientSecrets = new List<Secret>
{
new Secret("mysecret".Sha256())
},
AllowedScopes = new List<string>
{
Core.Constants.StandardScopes.OpenId,
Core.Constants.StandardScopes.Profile,
Core.Constants.StandardScopes.Email,
Core.Constants.StandardScopes.OfflineAccess
},
ClientUri = "https://localhost:44300/",
AccessTokenType = AccessTokenType.Jwt,
RedirectUris = new List<string>(),
PostLogoutRedirectUris = new List<string>
{
"https://localhost:44300/"
},
LogoutSessionRequired = true
};`
.Netcore api 启动如下所示
`public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "https://localhost:44300/ids";
options.ApiName = "iqimplicit";
options.ApiSecret = "mysecret";
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "SGPAY WebApi", Version = "v1" });
});
services.Configure<IdentityAppSettings>(Configuration.GetSection("IdentitySettings"));
services.AddDbContext<SGPAYDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SGPAYDatabase")));
RegisterDependencies.Register(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "SGPAY WebApi V1");
});
app.UseMvc();
}
}`
控制器如下所示:
`namespace Test
{
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
// GET: api/Test
[HttpGet]
public IActionResult Get()
{
return Ok(new LoginUser {UserName ="Test", Password="User" });
}
[Authorize]
[ValidateAntiForgeryToken]
// GET: api/Test/5
[HttpGet("{id}", Name = "Get")]
public string Get(int id)
{
return "value";
}
}
}`
在调用 http://localhost:2305/api/Test 时我应该得到 200 响应。但是我收到 401 未经授权的错误。
在您的控制器上使用 [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
而不是 [Authorize]
您需要在启动时注册不记名授权
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.Authority = "https://localhost:44300/ids",
options.RequireHttpsMetadata = false;
options.Audience = "iqimplict";
});
此示例适用于 IS4,因此您可能需要稍微调整一下以满足您的需要。但最主要的是你需要为你的控制器注册你的承载认证。
对于我的移动应用程序,我正在尝试创建一个安全的 API。我使用 ResourceOwner Flow 创建了一个带有身份服务器 3 的 oAuth 服务器。令牌生成成功。但是每当我调用受保护的 API 时,我都会收到 401-unauthorized 错误。
OAuth 服务器的代码下方
`var defaultmobileClient = new Client
{
ClientId = "iqimplicit",
ClientName = "iqimplicit",
Flow = Flows.ResourceOwner,
AllowAccessToAllScopes = true,
IdentityTokenLifetime = 300,//default value is 5 minutes this is the token that allows a user to login should only be used once
AccessTokenLifetime = 3600, // default is one hour access token is used for securing routes and access to api in IQ
RequireConsent = false,
RequireSignOutPrompt = true,
ClientSecrets = new List<Secret>
{
new Secret("mysecret".Sha256())
},
AllowedScopes = new List<string>
{
Core.Constants.StandardScopes.OpenId,
Core.Constants.StandardScopes.Profile,
Core.Constants.StandardScopes.Email,
Core.Constants.StandardScopes.OfflineAccess
},
ClientUri = "https://localhost:44300/",
AccessTokenType = AccessTokenType.Jwt,
RedirectUris = new List<string>(),
PostLogoutRedirectUris = new List<string>
{
"https://localhost:44300/"
},
LogoutSessionRequired = true
};`
.Netcore api 启动如下所示
`public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "https://localhost:44300/ids";
options.ApiName = "iqimplicit";
options.ApiSecret = "mysecret";
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "SGPAY WebApi", Version = "v1" });
});
services.Configure<IdentityAppSettings>(Configuration.GetSection("IdentitySettings"));
services.AddDbContext<SGPAYDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SGPAYDatabase")));
RegisterDependencies.Register(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "SGPAY WebApi V1");
});
app.UseMvc();
}
}`
控制器如下所示:
`namespace Test
{
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
// GET: api/Test
[HttpGet]
public IActionResult Get()
{
return Ok(new LoginUser {UserName ="Test", Password="User" });
}
[Authorize]
[ValidateAntiForgeryToken]
// GET: api/Test/5
[HttpGet("{id}", Name = "Get")]
public string Get(int id)
{
return "value";
}
}
}`
在调用 http://localhost:2305/api/Test 时我应该得到 200 响应。但是我收到 401 未经授权的错误。
在您的控制器上使用 [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize]
您需要在启动时注册不记名授权
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.Authority = "https://localhost:44300/ids",
options.RequireHttpsMetadata = false;
options.Audience = "iqimplict";
});
此示例适用于 IS4,因此您可能需要稍微调整一下以满足您的需要。但最主要的是你需要为你的控制器注册你的承载认证。