aspnetcore 應用 接入 Keycloak 快速上手指南
登錄及身份認證是現代 web 應用最基本的功能之一,對於企業內部的系統,多個系統往往希望有一套 SSO 服務對企業用戶的登錄及身份認證進行統一的管理,提升用戶同時使用多個系統的體驗,Keycloak 正是爲此種場景而生。本文將簡明的介紹 Keycloak 的安裝、使用,並給出 aspnetcore 應用如何快速接入 Keycloak 的示例。
Keycloak 是什麼
Keycloak 是一種面向現代應用和服務的開源 IAM(身份識別與訪問管理)解決方案
Keycloak 常用核心概念介紹
-
Users: 用戶,使用並需要登錄系統的對象 -
Roles: 角色,用來對用戶的權限進行管理 -
Clients: 客戶端,需要接入 Keycloak 並被 Keycloak 保護的應用和服務 -
Realms: 領域,領域管理着一批用戶、證書、角色、組等,一個用戶只能屬於並且能登陸到一個域,域之間是互相獨立隔離的, 一個域只能管理它下面所屬的用戶
Keycloak 服務安裝及配置
安裝 Keycloak
Keycloak 安裝有多種方式,這裏使用 Docker 進行快速安裝
登錄後複製
訪問 http://localhost:8080 並點擊 Administration Console 進行登錄
創建 Realm
創建一個新的 realm: demo,後續所有的客戶端、用戶、角色等都在此 realm 中創建
創建客戶端
創建前端應用客戶端
創建一個新的客戶端:KeycloakAuthaspnet,Access Type 選擇 confidential
關於客戶端的訪問類型(Access Type)
上面創建的客戶端的訪問類型分別是 confidential,那麼爲什麼分別選擇這種類型,實際不同的訪問類型有什麼區別呢?
事實上,Keycloak 目前的訪問類型共有 3 種:
-
confidential:適用於服務端應用,且需要瀏覽器登錄以及需要通過密鑰獲取access token的場景。典型的使用場景就是服務端渲染的 web 系統。 -
public:適用於客戶端應用,且需要瀏覽器登錄的場景。典型的使用場景就是前端 web 系統,包括採用 vue、react 實現的前端項目等。 -
bearer-only:適用於服務端應用,不需要瀏覽器登錄,只允許使用bearer token請求的場景。典型的使用場景就是 restful api。
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/
相關文章:
- https://gruchalski.com/posts/2020-09-05-introduction-to-keycloak-authorization-services/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/gYle9J7Co8Yt-cC7SmCLIw