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的返回值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM