打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
WebAPI IdentityServer4身份验证及客户端访问实现
  
  根据博客园solenovex的《使用Identity Server 4建立Authorization Server》系列,老菜测试Asp.Net Core 2.0 WebAPI及IdentityServer4身份验证 ,并实现客户端访问。

1、 打开VS2017,新建项目,选择 .net core->ASP.NET Core Web应用程序,项目名称为MyWebAPI,选择WebAPI,完成项目创建。
2、工具菜单选择Nuget包管理,打开“管理解决方案的NuGet包”,查找并安装IdentityServer4和IdentityServer4.AccessTokenValida。
3、修改项目配置launchSettings.json:

    "profiles": {
        "MyWebAPI": {
            "commandName": "Project",
            "launchBrowser": true,
            "environmentVariables": {
                "ASPNETCORE_ENVIRONMENT": "Development"
            },
            "applicationUrl": "http://localhost:6000/"
        }
    }   
}

4、项目中建立Configuration目录,建InMemoryConfiguration.cs:

using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace MyWebAPI.Configuration
{
    public class InMemoryConfiguration
    {
        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
               
            };
        }
        public static IEnumerable<ApiResource> ApiResources()
        {
            return new[]
            {
                new ApiResource("socialnetwork", "社交网络")
                {
                    UserClaims = new [] { "email" }
                }
            };
        }

        public static IEnumerable<Client> Clients()
        {
            return new[]
            {
                new Client
                {
                    ClientId = "socialnetwork",
                    ClientSecrets = new [] { new Secret("secret".Sha256()) },
                    AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
                    AllowedScopes = new [] { "socialnetwork" }
                }
            };
                
        }

        public static IEnumerable<TestUser> Users()
        {
            return new[]
            {
                new TestUser
                {
                    SubjectId = "1",
                    Username = "mail@qq.com",
                    Password = "password",
                    Claims = new [] { new Claim("email", "mail@qq.com") }
                }
            };
        }
    }
}

5、 修改Startup.cs中的ConfigureServices
 
public void ConfigureServices(IServiceCollection services)
{
    services.AddIdentityServer()
         .AddDeveloperSigningCredential()
         .AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources())
         .AddTestUsers(InMemoryConfiguration.Users().ToList())
         .AddInMemoryClients(InMemoryConfiguration.Clients())
         .AddInMemoryApiResources(InMemoryConfiguration.ApiResources());
   

    services.AddMvcCore()
    .AddAuthorization()
    .AddJsonFormatters();

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

6、修改Startup.cs中的Configure

public void Configure(IApplicationBuilder app, IHostingEnvironment env)        
{
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }  
            app.UseIdentityServer();
            app.UseStaticFiles();
            app.UseAuthentication();
            app.UseMvcWithDefaultRoute();
            
}

7、修改示例API控制器——ValuesController
[Authorize]
[Route("api/[controller]")]
public class ValuesController : Controller
{
     // GET api/values
     [HttpGet]
public JsonResult Get()
{
  JsonResult a = new JsonResult(new string[]{ "value1", "value2" });
  return a;
     }
}

8、运行项目,弹出dotnet console窗体,并在项目根目录生成临时证书tempkey.rsa

9、运行Postman,在builder中创建POST标签窗口,POST测试获取token

 
 
 
即可获得token。

10、客户端之一(IdentityModel): 新建.net Core 2 console控制台应用项目MyClient。通过“管理解决方案的NuGet包”,查找并安装IdentityModel包。 代码如下:
using IdentityModel.Client;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace MyClient
{
    class Program
    {
        public static void Main(string[] args) => MainAsync().GetAwaiter().GetResult(); 
        private static async Task MainAsync()
        {
            //DiscoveryClient类:IdentityModel提供给我们通过基础地址(如:http://localhost:6000)
            //就可以访问令牌服务端;当然可以根据上面的restful api里面的url自行构建;上面就是通过基础地址,
            //获取一个TokenClient;(对应restful的url:token_endpoint= "http://localhost:6000/connect/token")

            var dico = await DiscoveryClient.GetAsync("http://localhost:6000");

            //token
            var tokenClient = new TokenClient(dico.TokenEndpoint, "socialnetwork", "secret");
            var tokenresp = await tokenClient.RequestClientCredentialsAsync("socialnetwork");
            if (tokenresp.IsError)
            {
                Console.WriteLine(tokenresp.Error);
                return;

            }

            Console.WriteLine(tokenresp.Json);
            Console.WriteLine("\n\n");


            var client = new HttpClient();
            client.SetBearerToken(tokenresp.AccessToken);
            var resp = await client.GetAsync("http://localhost:6000/api/values");
            //var resp = await client.GetAsync("http://localhost:6000/identity");
            if (!resp.IsSuccessStatusCode)
            {
                Console.WriteLine(resp.StatusCode);
            }
            else
            {
                var content = await resp.Content.ReadAsStringAsync();
                Console.WriteLine(JArray.Parse(content));
            }

            Console.ReadKey(true);


        }
    }
}
结果:

 
 

11、客户端之一(Restsharp),另外新建.net Core 2 console控制台应用项目MyjwtClient。通过“管理解决方案的NuGet包”,查找并安装Restsharp、Newtonsoft.Json包。 代码如下:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using RestSharp.Authenticators;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyClient
{
    class Program
    {
        /// <summary>
        /// 访问Url
        /// </summary>
        static string _url = "http://localhost:6000";
        static void Main(string[] args)
        {
            var client = new RestClient(_url);

            RestRequest request = CreatePostTokenRestRequest(client);

            var response = client.Execute(request);
            JObject jo = (JObject)JsonConvert.DeserializeObject(response.Content);

            Console.WriteLine(response.Content);

            string access_token = jo["access_token"].ToString();

            RestRequest requestapi = CreateGetApiRestRequestByToken(access_token);
            var responseapi = client.Execute(requestapi); 

            Console.WriteLine(responseapi.Content);
              
            Console.ReadKey(true);

        }

        private static RestRequest CreateGetApiRestRequestByToken(string access_token)
        {
            RestRequest requestapi = new RestRequest() { Method = Method.GET };

            requestapi.AddHeader("Content-Type", "application/x-www-form-urlencoded");
            requestapi.AddHeader("Accept", "application/json");
            requestapi.AddHeader("authorization", string.Format("Bearer {0}", access_token));

            requestapi.Resource = "/api/values";
            return requestapi;
        }

        private static RestRequest CreatePostTokenRestRequest(RestClient client)
        {
            RestRequest request = new RestRequest() { Method = Method.POST }; 
            client.Authenticator = new HttpBasicAuthenticator("socialnetwork", "secret"); 
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
            request.AddHeader("Accept", "application/json");
            request.AddParameter("client_id", "socialnetwork");
            request.AddParameter("client_secret", "secret");
            request.AddParameter("grant_type", "password");
            request.AddParameter("username", "mail@qq.com");
            request.AddParameter("password", "password");
            request.Resource = "/connect/token";
            return request;
        }

        private static RestRequest CreatePostRefresfTokenRestRequest(RestClient client)
        {
            RestRequest request = new RestRequest() { Method = Method.POST };
            client.Authenticator = new HttpBasicAuthenticator("socialnetwork", "secret");
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
            request.AddHeader("Accept", "application/json");
            request.AddParameter("client_id", "mvc_code");
            request.AddParameter("client_secret", "secret");
            request.AddParameter("grant_type", "hybird");
            request.AddParameter("username", "mail@qq.com");
            request.AddParameter("password", "password");
            request.Resource = "/connect/token";
            return request;
        }
    }
}

12、先运行MyWebApi,后运行MyClient
 
 
在MyClient中通过RestRequest获取response,通过JsonConvert.DeserializeObject解析response内容中的access_token,然后通过创建WebAPI请求的RestRequest,根据access_token,获得webapi的返回值。






本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Restsharp常见格式的发送分析
IdentityServer4 (4) 静默刷新(Implicit)
IdentityServer4 (1) 客户端授权模式(Client Credentials)
如何利用 C# 爬取带 Token 验证的网站数据?
.NET Core 下调用WebAPI
用Java和Perl登录新浪微博
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服