aspnetcore 应用 接入Keycloak快速上手指南
登錄及身份認證是現代web應用最基本的功能之一,對于企業內部的系統,多個系統往往希望有一套SSO服務對企業用戶的登錄及身份認證進行統一的管理,提升用戶同時使用多個系統的體驗,Keycloak正是為此種場景而生。本文將簡明的介紹Keycloak的安裝、使用,并給出aspnetcore 應用如何快速接入Keycloak的示例。
Keycloak是什么
Keycloak是一種面向現代應用和服務的開源IAM(身份識別與訪問管理)解決方案
Keycloak提供了單點登錄(SSO)功能,支持OpenID Connect、OAuth 2.0、SAML 2.0標準協議,擁有簡單易用的管理控制臺,并提供對LDAP、Active Directory以及Github、Google等社交賬號登錄的支持,做到了非常簡單的開箱即用。
官網:https://www.keycloak.org/
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: 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 p
????????? */
???????
???????? //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/?
相關文章:
https://gruchalski.com/posts/2020-09-05-introduction-to-keycloak-authorization-services/
總結
以上是生活随笔為你收集整理的aspnetcore 应用 接入Keycloak快速上手指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快速打造一个MINI自动发布系统
- 下一篇: 前端老弟第一次写后端,崩了!