登入及身份認證是現代web應用最基本的功能之一,對於企業內部的系統,多個系統往往希望有一套SSO服務對企業使用者的登入及身份認證進行統一的管理,提升使用者同時使用多個系統的體驗,Keycloak正是為此種場景而生。本文將簡明的介紹Keycloak的安裝、使用,並給出aspnetcore 應用如何快速接入Keycloak的示例。
Keycloak是什麼
Keycloak是一種面向現代應用和服務的開源IAM(身份識別與訪問管理)解決方案
Keycloak提供了單點登入(SSO)功能,支援OpenID Connect
、OAuth 2.0
、SAML 2.0
標準協議,擁有簡單易用的管理控制檯,並提供對LDAP、Active Directory以及Github、Google等社交賬號登入的支援,做到了非常簡單的開箱即用。
Keycloak常用核心概念介紹
首先通過官方的一張圖來了解下整體的核心概念
這裡先只介紹4個最常用的核心概念:
-
Users
: 使用者,使用並需要登入系統的物件 -
Roles
: 角色,用來對使用者的許可權進行管理 -
Clients
: 客戶端,需要接入Keycloak並被Keycloak保護的應用和服務 Realms
: 領域,領域管理著一批使用者、證書、角色、組等,一個使用者只能屬於並且能登陸到一個域,域之間是互相獨立隔離的, 一個域只能管理它下面所屬的使用者
Keycloak服務安裝及配置
安裝Keycloak
Keycloak安裝有多種方式,這裡使用Docker進行快速安裝
登入後複製
docker run -d --name keycloak \
-p 8080:8080 \
-e KEYCLOAK_USER=admin \
-e KEYCLOAK_PASSWORD=admin \
jboss/keycloak:13.0.0
訪問http://localhost:8080並點選Administration Console進行登入
建立Realm
首先,我們需要建立一個Realm。Realm是一個隔離的概念,Realm A中的使用者與Realm B中的使用者完全隔離。建立一個新的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 包
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<UserSecretsId>afab524d-850e-499a-bc13-98f61ca0eb3b</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
</ItemGroup>
</Project>
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
*/
/*
* Policy based authentication
*/
services.AddAuthorization(options =>
{
//Create policy with more than one claim
options.AddPolicy("users", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
(c.Value == "user") || (c.Value == "admin"))));
//Create policy with only one claim
options.AddPolicy("admins", policy =>
policy.RequireClaim(ClaimTypes.Role, "admin"));
//Create a policy with a claim that doesn't exist or you are unauthorized to
options.AddPolicy("noaccess", policy =>
policy.RequireClaim(ClaimTypes.Role, "noaccess"));
});
/*
* Non policy based authentication
* Uncomment below and comment the policy section
*/
//services.AddAuthorization();
}
經過上述的配置,通過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/
相關文章: