api未授权怎么回事,api未授权怎么解决

  

  .Net Core 3.0 IdentityServer4 快速入门―― resource owner password credentials(密码模式)   

  

  一、前言   

  

  默认情况下, OAuth 2.0有四种授权类型:   

  

  1)授权码模式   

  

  2)简化模式   

  

  3)密码模式(资源所有者密码凭证)   

  

  4)客户端模式(客户端凭据)   

  

  上一节接受了客户端模式,本节将介绍密码模式。OAuth2.0资源所有者的密码授权功能允许客户端将用户名和密码发送到授权服务器,并获取用户的访问令牌。   

  

  认证步骤:   

  

     

  

  1)用户向客户端提供用户名和密码   

  

  2)客户端将用户名和密码发送到授权服务器(Id4)以请求令牌。   

  

  3)授权服务器(Id4)验证用户的有效性,并将其返回给客户端令牌。   

  

  4)4)Api资源收到第一个(第一个)请求后,会从授权服务器(Id4)获取公钥,然后用公钥验证令牌是否合法。如果合法,后续的请求将通过第一个请求的公钥进行验证(jwt分散验证思想)   

  

  资源所有者实际上是用户。与客户端模式相比,密码模式多了一个参与者,即用户,通过用户的用户名和密码向身份服务器申请访问令牌。在这种模式下,要求客户端不存储密码,但是我们不能保证客户端是否存储密码,所以这种模式只适用于可信客户端。因此,不推荐这种模式。   

  

  二、创建授权服务器   

  

     

  

  1)安装Id4   

  

     

  

  2)创建一个Config类来模拟要保护的资源和可以访问的api客户端服务器的配置。   

  

  使用IdentityServer4使用IdentityServer4。模特;使用IdentityServer4。测试;使用系统。集合。泛型;命名空间Identity Server 02 {公共静态类配置{//summary//要保护的api资源///summary公共静态ienumerableresource API=new listapiresource { new API resource(' API 1 ',' my API ')};public static ienumerableclient=new list client {//client new client { clientid=' client ',client secret={ new secret(' aju ' . sha 256())},Allowed types=grant types . resourceownerpassword,//如果要获取refresh_tokens,必须添加脱机访问允许的作用域={'API 1 ',IdentityServerConstants。StandardScopes.OfflineAccess},AllowOfflineAccess=true } }public static listestuser Users=new listestuser { new TestUser { SubjectId=' 001 ',Password='Aju_001 ',Username='Aju_001' },new TestUser { SubjectId='002 ',Password=' Aju _ 002 ' } };}}与客户端模式不一致的是,这里将(allowedGranttypes=grant types . resourceownerpassword)设置为资源所有者(密码模式)。   

  

  3)配置启动   

  

  使用微软。AspNetCore . Builder使用微软。AspNetCore.H   

osting;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;namespace IdentityServer02{ 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) { var builder = services.AddIdentityServer() .AddInMemoryApiResources(Config.Apis) .AddInMemoryClients(Config.Clients) .AddTestUsers(Config.Users);19 builder.AddDeveloperSigningCredential(); } // 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.UseRouting(); app.UseIdentityServer(); } }}5)验证配置是否成功

  

在浏览器中输入(http://localhost:5000/.well-known/openid-configuration)看到如下发现文档算是成功的

  

  

三、创建Api资源

  

1)步骤如创建授权服务的1)

  

2)安装包

  

  

3)创建一个受保护的ApiController

  

using Microsoft.AspNetCore.Authorization;using Microsoft.AspNetCore.Mvc;using System.Linq;namespace Api02.Controllers{ public class ApiController : ControllerBase { public IActionResult Get() { return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); } }} 4)配置StartUp

  

using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Hosting;using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;namespace Api02{ 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.AddControllers(); services.AddAuthentication("Bearer").AddJwtBearer("Bearer", options => { options.Authority = "http://localhost:5000"; options.RequireHttpsMetadata = false; options.Audience = "api1"; }); } // 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.UseRouting(); app.UseAuthentication();//认证 app.UseAuthorization();//授权 app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }}四、创建客户端(控制台 模拟客户端)

  

using IdentityModel.Client;using Newtonsoft.Json.Linq;using System;using System.Net.Http;using System.Threading.Tasks;namespace Client02{ class Program { static async Task Main(string<> args) { // Console.WriteLine("Hello World!"); var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000"); if (disco.IsError) { Console.WriteLine(disco.Error); return; } var tokenResponse = await client.RequestPasswordTokenAsync( new PasswordTokenRequest { Address = disco.TokenEndpoint, ClientId = "client", ClientSecret = "aju", Scope = "api1 offline_access", UserName = "Aju", Password = "Aju_password" }); if (tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return; } Console.WriteLine(tokenResponse.Json); Console.WriteLine("\n\n"); //call api var apiClient = new HttpClient(); apiClient.SetBearerToken(tokenResponse.AccessToken); var response = await apiClient.GetAsync("http://localhost:5001/api"); if (!response.IsSuccessStatusCode) { Console.WriteLine(response.StatusCode); } else { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(JArray.Parse(content)); } Console.ReadLine(); } }}五、验证

  

1)直接获取Api资源

  

  

出现了401未授权提示,这就说明我们的Api需要授权

  

2)运行客户端访问Api资源

  

  

六、自定义用户验证

  

在创建授权服务器的时候我们在Config中默认模拟(写死)两个用户,这显得有点不太人性化,那我们就来自定义验证用户信息

  

1)创建 自定义 验证 类 ResourceOwnerValidator

  

using IdentityModel;using IdentityServer4.Models;using IdentityServer4.Validation;using System.Threading.Tasks;namespace IdentityServer02{ public class ResourceOwnerValidator : IResourceOwnerPasswordValidator { public Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { if (context.UserName == "Aju" && context.Password == "Aju_password") { context.Result = new GrantValidationResult( subject: context.UserName, authenticationMethod: OidcConstants.AuthenticationMethods.Password); } else { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "无效的秘钥"); } return Task.FromResult(""); } }}2)在授权服务器StartUp配置类中,修改如下:

  

  

3)在客户端中将 用户名 和 密码 修改成 我们在自定义 用户 验证类 中写的用户名和密码,进行测试

  

七、通过refresh_token 获取 Token

  

1)refresh_token

  

获取请求授权后会返回 access_token、expire_in、refresh_token 等内容,每当access_token 失效后用户需要重新授权,但是有了refresh_token后,客户端(Client)检测到Token失效后可以直接通过refresh_token向授权服务器申请新的token

  

  

八、参考文献

  

http://docs.identityserver.io/en/latest/index.html

  

如果对您有帮助,请点个推荐(让更多需要的人看到哦)

  

相关文章