zoukankan      html  css  js  c++  java
  • 使用Identity Server 4建立Authorization Server (2)

    第一部分: http://www.cnblogs.com/cgzl/p/7780559.html

    第一部分主要是建立了一个简单的Identity Server.

    接下来继续:

    建立Web Api项目

    如图可以在同一个解决方案下建立一个web api项目:

    (可选)然后修改webapi的launchSettings.json, 我习惯使用控制台, 所以把IISExpress相关的都删掉, 并且把端口改成5001:

    {
      "profiles": {
        "WebApi": {
          "commandName": "Project",
          "launchBrowser": true,
          "launchUrl": "api/values",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          },
          "applicationUrl": "http://localhost:5001/"
        }
      }
    }

    为Web Api添加Swagger帮助页面

    完全依照官方文档安装swagger即可: https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?tabs=visual-studio

    通过nuget安装或者通过package manager console:

    Install-Package Swashbuckle.AspNetCore

    在Startup的ConfigureServices注册并配置Swagger, 然后在StartUp的Configure方法使用Swagger中间件:

    // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc();
                // Register the Swagger generator, defining one or more Swagger documents
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
                });
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    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", "My API V1");
                });
    
                app.UseMvc();
            }

    可以运行一下项目, 通过地址: http://localhost:5001/swagger/ 访问swagger帮助页面:

    添加库IdentityServer4.AccessTokenValidation

    webapi配置identity server就需要对token进行验证, 这个库就是对access token进行验证的. 通过nuget安装:

    在Startup的ConfigureServices里面注册配置:

    services.AddMvcCore()
                    .AddAuthorization()
                    .AddJsonFormatters();
    
                services.AddAuthentication("Bearer")
                    .AddIdentityServerAuthentication(options =>
                    {
                        options.RequireHttpsMetadata = false;
                        options.Authority ="http://localhost:5000";
                        options.ApiName = "socialnetwork";
                    });

    这里AddAuthentication()是把验证服务注册到DI, 并配置了Bearer作为默认模式.

    AddIdentityServerAuthentication()是在DI注册了token验证的处理者.

    由于是本地运行, 所以就不使用https了, RequireHttpsMetadata = false. 如果是生产环境, 一定要使用https.

    Authority指定Authorization Server的地址.

    ApiName要和Authorization Server里面配置ApiResource的name一样.

    然后, 在Startup的Configure方法里配置Authentication中间件.

    app.UseAuthentication();
    
    app.UseMvc();

    这句话就是在把验证中间件添加到管道里, 这样每次请求就会调用验证服务了. 一定要在UserMvc()之前调用.

    当在controller或者Action使用[Authorize]属性的时候, 这个中间件就会基于传递给api的Token来验证Authorization, 如果没有token或者token不正确, 这个中间件就会告诉我们这个请求是UnAuthorized(未授权的).

    添加[Authorize]属性:

    打开ValuesController, 在Controller上面添加这个属性:

        [Authorize]
        [Route("api/[controller]")]
        public class ValuesController : Controller

    然后运行 webapi:

    会自动打开这个网址: http://localhost:5001/api/values

    Chrome按F12, 打开调试窗口的network折页 (按F12以后可能需要刷新一下浏览器):

    401, 显示该请求为UnAuthorized.

    也可以使用postman:

    还是401.

    也可以使用swagger, 依然401:

    所以我们首先需要获取到一个token. 不过需要把Authorization Server也跑起来.

    点击解决方案属性, 让两个项目都启动:

    然后运行, 使用postman先获取token:

     

    如果报错的话, 可能是生成的证书有问题, 上次文章里面有一个参数rsa我后边写的是2014, 写错了, 应该是2048. 如果报错就重新生成一个吧.

    然后复制一下 access_token的值. 回到api/values的那个请求, 把access_token贴到Authorization Header的值里面, 前边要加上Bearer表示类型, 还有一个空格.

    这样, 请求就会通过验证, 返回200和正确的值.

    看一下Authorization Server的控制台信息:

    会发现有人请求了这个地址, 事实上这就是api从identity server请求获取public key, 然后在webapi里用它来验证token.

    如果你改变了token的一个字母, 请求结果就会变成401.

    在ValuesController里面设断点看看Claims

    使用User.Claims来获取claims.

    看看claims, 里面包含着authorization server的信息, 包括client, scope等等. 这些都是从token里面来的, 这个token在这肯定不是被篡改过的, 因为它已经从authorization server验证过了.

    上面这种验证 我们使用的是client_credentials. 下面我们使用resourceownerpassword这个flow来试试:

    在postman里面这样请求token, grant_type改成password, 然后添加username和password:

    然后复制token, 请求api/values, 还看那个断点:

    这时claims和之前不一样了. 这里有sub (subject), 它是用户的id, 还有一些其他信息.

    分析一下Token

    https://jwt.io/ 可以分析一下这个token:

    token分为三个部分, 每个部分之间使用一个点来分开.

    我们知道第一个部分是Header, 包括算法和类型等信息:

    第二部分是Payload(数据), 就是断点里Claims的数据:

    第三部分是签名:

     比较忙, 这次写的比较少. 看来还能写很多集... - -!

  • 相关阅读:
    关于C的一些理解
    Linux下/proc目录简介
    python学习链接
    “段寄存器”的故事[转](彻底搞清内存段/elf段/实模式保护模式以及段寄存器)
    内核态与用户态
    bzoj1087: [SCOI2005]互不侵犯King 状压dp
    bzoj1007: [HNOI2008]水平可见直线 单调栈维护凸壳
    bzoj1015: [JSOI2008]星球大战starwar
    bzoj1002: [FJOI2007]轮状病毒 生成树计数
    bzoj1013: [JSOI2008]球形空间产生器sphere
  • 原文地址:https://www.cnblogs.com/cgzl/p/7788636.html
Copyright © 2011-2022 走看看