(二)單點登錄統一認證(SSO)簡單實現


前面已經闡述了單點登錄統一認證的核心框架基礎 (一)IdentityServer 4 基礎,接下來就進行簡單實現

開發工具及框架:

        Visual Studio

        .NET CORE 版本: 2.1

        NuGet包:IdentityServer 4

一、新建 IdentityServer 4 認證應用程序(快速創建/手動創建)

1.手動使用 VS 創建

        打開 VS,新建 ASP.NET Core 2.1 應用程序 QuickStart

        展開項目,右鍵依賴項,選擇管理 NuGet 程序包,輸入 IdentityServer 4 選擇低於 3.0 版本安裝。

        在項目下新建 Config.cs 文件

(.NET CORE 2.1 對應的 Microsoft.AspNetCore.Razor.Design 版本為 2.1.2,打開 csproj 文件修改)

2.使用控制台快速創建

md quickstart
cd quickstart

md src
cd src
dotnet new is4empty -n IdentityServer

cd..
dotnet new sln -n Quickstart
dotnet sln add .\src\IdentityServer\IdentityServer.csproj

        這將創建以下基礎項目文件及添加 IdentityServer 項目:

        Properties\launchSettings.json 配置文件
        IdentityServer.csproj 項目文件
        Program.cs 和 Startup.cs 主應用程序入口點
        Config.cs IdentityServer 資源和客戶端配置文件

注:Properties\launchSettings.json 配置文件包含運行端口,如果需要修改可修改該文件。

3.定義 API 資源

        API 是系統中要保護的資源,資源定義可以通過多種方式加載。打開 Config.cs 文件,增加 API 資源

public static IEnumerable<ApiResource> GetApis()
{
    return new List<ApiResource>
    {
        new ApiResource("api1", "My API")
    };
}

4.定義客戶端

        客戶端用於訪問 API 資源,還是打開 Config.cs 文件,增加客戶端

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        new Client
        {
            ClientId = "client",

            // no interactive user, use the clientid/secret for authentication
            AllowedGrantTypes = GrantTypes.ClientCredentials,

            // secret for authentication
            ClientSecrets =
            {
                new Secret("secret".Sha256())
            },

            // scopes that client has access to
            AllowedScopes = { "api1" }
        }
    };
}

5.配置 IdentityServer 4

        前面已經引入了 NuGet 包 IdentityServer 4,所以直接打開 Startup.cs 文件配置 IdentityServer 4

public void ConfigureServices(IServiceCollection services)
{
    var builder = services.AddIdentityServer()
        .AddInMemoryIdentityResources(Config.GetIdentityResources())
        .AddInMemoryApiResources(Config.GetApis())
        .AddInMemoryClients(Config.GetClients());

    // omitted for brevity
}

        到此,一個基礎的 IdentityServer 4 身份認證服務器已配置完成,運行服務器並打開 http://localhost:5000/.well-known/openid-configuration 可以看到端點配置文件,客戶端和 API 會通過該文件獲取對於信息。

 二、后台 API 服務

        有了身份認證服務器,接下來就需要 API 服務。

1.手動創建

        右鍵解決方案,添加新建項目 Api,選擇 ASP.NET Core 應用程序,選擇 Web 應用程序(模型視圖控制器),包含控制器是便於后續增加 Swagger 接口文檔。

2.控制台快速創建(若.NET CORE 版本高於2.1需要修改配置文件,推薦使用手動創建方法)

        打開控制台,進入項目,執行以下命令

cd quickstart

cd src
dotnet new web -n Api
cd..
dotnet sln add .\src\Api\Api.csproj

        項目創建完成后,修改 Properties\launchSettings.json 配置文件的運行端口為 5001(認證服務器端口為 5000)。

"applicationUrl": "http://localhost:5001"

3.新增 Controllers

        添加新文件夾 Controllers 和新控制器 IdentityController,VS 創建的項目直接新增 IdentityController 控制器即可。

[Route("identity")]
[Authorize]
public class IdentityController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
    }
}

 4.配置依賴

        將身份驗證服務添加到DI(依賴注入),並將身份驗證中間件添加到管道。打開 Api 的 Startup.cs 文件。

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvcCore()
            .AddAuthorization()
            .AddJsonFormatters();

        services.AddAuthentication("Bearer")
            .AddJwtBearer("Bearer", options =>
            {
                options.Authority = "http://localhost:5000";
                options.RequireHttpsMetadata = false;

                options.Audience = "api1";
            });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseAuthentication();

        app.UseMvc();
    }
}

        AddAuthentication 將身份驗證服務添加到DI並配置"Bearer"為默認方案,UseAuthentication 將身份驗證中間件添加到管道中,以便對主機的每次調用都將自動執行身份驗證。

        http://localhost:5001/identity 在瀏覽器上導航至控制器應返回401狀態代碼。這表示 API 現在受 IdentityServer 保護,訪問需要憑據。

        至此,后台 API 服務已經創建完成,接下來創建一個客戶端進行認證訪問及 API 調用。

三、創建客戶端

1.手動創建

        右鍵解決方案,新建控制台應用

2.快速創建

cd quickstart

cd src
dotnet new console -n Client

cd ..
dotnet sln add .\src\Client\Client.csproj

3.修改啟動文件

    打開 NuGet 程序包,添加 IdentityModel,並修改 Program.cs 文件如下

using IdentityModel.Client;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace Client
{
    public class Program
    {
        private static async Task Main()
        {
            // discover endpoints from metadata
            var client = new HttpClient();

            var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
            if (disco.IsError)
            {
                Console.WriteLine(disco.Error);
                return;
            }

            // request token
            var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
            {
                Address = disco.TokenEndpoint,
                ClientId = "client",
                ClientSecret = "secret",

                Scope = "api1"
            });

            if (tokenResponse.IsError)
            {
                Console.WriteLine(tokenResponse.Error);
                return;
            }

            Console.WriteLine(tokenResponse.Json);
            Console.WriteLine("\n\n");
            Console.ReadLine();

            // call api
            var apiClient = new HttpClient();
            apiClient.SetBearerToken(tokenResponse.AccessToken);

            var response = await apiClient.GetAsync("http://localhost:5001/identity");
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Console.WriteLine(JArray.Parse(content));
            }
            Console.ReadLine();
        }
    }
}

        至此一個簡單的包含身份服務器,API 服務器,控制台應用的項目完成,運行身份服務器,API 服務器,控制台應用,控制台應用輸出如下

四、添加需要用戶名和密碼的客戶端

1.添加測試用戶

        修改 IdentityServer 認證服務的 Config.cs文件

using IdentityServer4.Test;

public static List<TestUser> GetUsers()
{
    return new List<TestUser>
    {
        new TestUser
        {
            SubjectId = "1",
            Username = "alice",
            Password = "password"
        },
        new TestUser
        {
            SubjectId = "2",
            Username = "bob",
            Password = "password"
        }
    };
}

        然后在 Startup.cs 中注冊測試用戶

public void ConfigureServices(IServiceCollection services)
{
    // configure identity server with in-memory stores, keys, clients and scopes
    services.AddIdentityServer()
        .AddInMemoryApiResources(Config.GetApiResources())
        .AddInMemoryClients(Config.GetClients())
        .AddTestUsers(Config.GetUsers());
}

2.添加新客戶端配置

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        // other clients omitted...

        // resource owner password grant client
        new Client
        {
            ClientId = "ro.client",
            AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,

            ClientSecrets =
            {
                new Secret("secret".Sha256())
            },
            AllowedScopes = { "api1" }
        }
    };
}

3.通過用戶名和密碼進行授權

        修改控制台應用 Client 的 Program.cs 文件,增加新的授權方式

// request token
var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
    Address = disco.TokenEndpoint,
    ClientId = "ro.client",
    ClientSecret = "secret",

    UserName = "alice",
    Password = "password",
    Scope = "api1"
});

if (tokenResponse.IsError)
{
    Console.WriteLine(tokenResponse.Error);
    return;
}

Console.WriteLine(tokenResponse.Json);

        新的客戶端需要傳輸用戶名和密碼才能通過授權

        更多 IdentityServer 示例請移步官方文檔地址


免責聲明!

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



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