aspnetcore 應用 接入 Keycloak 快速上手指南

登錄及身份認證是現代 web 應用最基本的功能之一,對於企業內部的系統,多個系統往往希望有一套 SSO 服務對企業用戶的登錄及身份認證進行統一的管理,提升用戶同時使用多個系統的體驗,Keycloak 正是爲此種場景而生。本文將簡明的介紹 Keycloak 的安裝、使用,並給出 aspnetcore 應用如何快速接入 Keycloak 的示例。

Keycloak 是什麼

Keycloak 是一種面向現代應用和服務的開源 IAM(身份識別與訪問管理)解決方案

Keycloak 常用核心概念介紹

  1. Users: 用戶,使用並需要登錄系統的對象

  2. Roles: 角色,用來對用戶的權限進行管理

  3. Clients: 客戶端,需要接入 Keycloak 並被 Keycloak 保護的應用和服務

  4. Realms: 領域,領域管理着一批用戶、證書、角色、組等,一個用戶只能屬於並且能登陸到一個域,域之間是互相獨立隔離的, 一個域只能管理它下面所屬的用戶

Keycloak 服務安裝及配置

安裝 Keycloak

Keycloak 安裝有多種方式,這裏使用 Docker 進行快速安裝

登錄後複製

訪問 http://localhost:8080 並點擊 Administration Console 進行登錄

創建 Realm

創建一個新的 realm: demo,後續所有的客戶端、用戶、角色等都在此 realm 中創建

創建客戶端
創建前端應用客戶端

創建一個新的客戶端:KeycloakAuthaspnet,Access Type 選擇 confidential

關於客戶端的訪問類型(Access Type)

上面創建的客戶端的訪問類型分別是 confidential,那麼爲什麼分別選擇這種類型,實際不同的訪問類型有什麼區別呢?

事實上,Keycloak 目前的訪問類型共有 3 種:

Access Type 裏面選 Confidential,然後纔有 Client Secret ,保存之後,會出現 Credentials 的 Tab,記錄下這裏的 secret,後面要用到

創建用戶和角色
創建角色

創建 2 個角色:admin、user

還可以創建全局的角色

創建用戶

創建 1 個用戶:geffzhang

綁定用戶和角色
給 geffzhang 用戶分配角色 admin 和 user

aspnetcore 應用集成 Keycloak 簡明指南

添加 Microsoft.AspNetCore.Authentication.OpenIdConnect  和  Microsoft.AspNetCore.Identity 包

 
     net5.0
     afab524d-850e-499a-bc13-98f61ca0eb3b
     Linux
  

 
    
    
    
    
  

Appsettings.json

// This method gets called by the runtime. Use this method to add services to the container.
     public void ConfigureServices(IServiceCollection services)
     {
         services.AddControllersWithViews();
        
         services.AddAuthentication(options =>
         {
             //Sets cookie authentication scheme
             options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
             options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
             options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
         })

        .AddCookie(cookie =>
         {
             //Sets the cookie name and maxage, so the cookie is invalidated.
             cookie.Cookie.Name = "keycloak.cookie";
             cookie.Cookie.MaxAge = TimeSpan.FromMinutes(60);
             cookie.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
             cookie.SlidingExpiration = true;
         })
         .AddOpenIdConnect(options =>
         {
             /*
              * ASP.NET core uses the http://*:5000 and https://*:5001 ports for default communication with the OIDC middleware
              * The app requires load balancing services to work with :80 or :443
              * These needs to be added to the keycloak client, in order for the redirect to work.
              * If you however intend to use the app by itself then,
              * Change the ports in launchsettings.json, but beware to also change the options.CallbackPath and options.SignedOutCallbackPath!
              * Use LB services whenever possible, to reduce the config hazzle :)
             */

            //Use default signin scheme
             options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
             //Keycloak server
             options.Authority = Configuration.GetSection("Keycloak")["ServerRealm"];
             //Keycloak client ID
             options.ClientId = Configuration.GetSection("Keycloak")["ClientId"];
             //Keycloak client secret
             options.ClientSecret = Configuration.GetSection("Keycloak")["ClientSecret"];
             //Keycloak .wellknown config origin to fetch config
             options.MetadataAddress = Configuration.GetSection("Keycloak")["Metadata"];
             //Require keycloak to use SSL
             options.RequireHttpsMetadata = false;
             options.GetClaimsFromUserInfoEndpoint = true;
             options.Scope.Add("openid");
             options.Scope.Add("profile");
             //Save the token
             options.SaveTokens = true;
             //Token response type, will sometimes need to be changed to IdToken, depending on config.
             options.ResponseType = OpenIdConnectResponseType.Code;
             //SameSite is needed for Chrome/Firefox, as they will give http error 500 back, if not set to unspecified.
             options.NonceCookie.SameSite = SameSiteMode.Unspecified;
             options.CorrelationCookie.SameSite = SameSiteMode.Unspecified;
            
             options.TokenValidationParameters = new TokenValidationParameters
             {
                 NameClaimType = "name",
                 RoleClaimType = ClaimTypes.Role,
                 ValidateIssuer = true
             };

         });

        /*
          * For roles, that are defined in the keycloak, you need to use ClaimTypes.Role
          * You also need to configure keycloak, to set the correct name on each token.
          * Keycloak Admin Console -> Client Scopes -> roles -> mappers -> create
          * Name: "role client mapper" or whatever you prefer
          * Mapper Type: "User Client Role"
          * Multivalued: True
          * Token Claim Name: role
          * Add to access token: True
          */

    }

經過上述的配置,通過 oidc 很容易就接入到了 Keycloak。具體代碼請參見:https://github.com/NanoFabricFX/AspNetCore-keycloak/tree/dotnet5。

運行效果,第一次訪問項目會跳轉 Keycloak 登錄頁

用戶登陸 geffzhang

總結

Keycloak 部署及接入簡單,輕量的同時功能又不失強大,非常適合企業內部的 SSO 方案。在 Identity Server4 收費的背景之下,微軟計劃在. NET 6 裏面繼續集成,已經被社區罵的狗血噴頭 https://devblogs.microsoft.com/aspnet/asp-net-core-6-and-authentication-servers/ 

相關文章:

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/gYle9J7Co8Yt-cC7SmCLIw