登录及身份认证是现代web应用最基本的功能之一,对于企业内部的系统,多个系统往往希望有一套SSO服务对企业用户的登录及身份认证进行统一的管理,提升用户同时使用多个系统的体验,Keycloak正是为此种场景而生。本文将简明的介绍Keycloak的安装、使用,并给出aspnetcore 应用如何快速接入Keycloak的示例。

Keycloak是什么

Keycloak是一种面向现代应用和服务的开源IAM(身份识别与访问管理)解决方案

Keycloak提供了单点登录(SSO)功能,支持OpenID ConnectOAuth 2.0SAML 2.0标准协议,拥有简单易用的管理控制台,并提供对LDAP、Active Directory以及Github、Google等社交账号登录的支持,做到了非常简单的开箱即用。

官网: https://www.keycloak.org/

Keycloak常用核心概念介绍

首先通过官方的一张图来了解下整体的核心概念

这里先只介绍4个最常用的核心概念:

  1. Users: 用户,使用并需要登录系统的对象

  2. Roles: 角色,用来对用户的权限进行管理

  3. Clients: 客户端,需要接入Keycloak并被Keycloak保护的应用和服务

  4. 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选择public

关于客户端的访问类型(Access Type)

上面创建的2个客户端的访问类型分别是public、bearer-only,那么为什么分别选择这种类型,实际不同的访问类型有什么区别呢?

事实上,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/

相关文章:

aspnetcore 应用 接入Keycloak快速上手指南的更多相关文章

  1. Keycloak快速上手指南,只需10分钟即可接入Spring Boot/Vue前后端分离应用实现SSO单点登录

    登录及身份认证是现代web应用最基本的功能之一,对于企业内部的系统,多个系统往往希望有一套SSO服务对企业用户的登录及身份认证进行统一的管理,提升用户同时使用多个系统的体验,Keycloak正是为此种 ...

  2. Rancher 快速上手指南操作(1)

    Rancher 快速上手指南操作(1)该指南知道用户如何快速的部署Rancher Server 管理容器.前提是假设你的机器已经安装好docker了.1 确认 docker 的版本,下面是 ubunt ...

  3. UnityShader快速上手指南(三)

    简介 这一篇还是一些基本的shader操作:裁剪.透明和法向量的应用 (纠结了很久写不写这些,因为代码很简单,主要是些概念上的东西) 先来看下大概的效果图:(从左到右依次是裁剪,透明,加了法向量的透明 ...

  4. [转]Rancher 快速上手指南操作(1)

    本文转自:http://www.cppblog.com/zhiyewang/archive/2016/03/17/213053.aspx Rancher 快速上手指南操作(1)该指南知道用户如何快速的 ...

  5. Markdown快速上手指南

    Markdown快速上手指南 1.Markdown介绍 markdown可以实现快速html文档编辑,格式优没,并且不需要使用html元素. markdown采用普通文本的形式,例如读书笔记等易于使用 ...

  6. Github Action 快速上手指南

    前言 各位读者,新年快乐,我是过了年匆忙赶回上海努力搬砖的蛮三刀. Github之前更新了一个Action功能(应该是很久以前了),可以实现很多自动化操作.用来替代用户自己设置的自动化脚本(比如:钩子 ...

  7. UnityShader快速上手指南(二)

    简介 前一篇介绍了如果编写最基本的shader,接下来本文将会简单的深入一下,我们先来看下效果吧 呃,gif效果不好,实际效果是很平滑的动态过渡 实现思路 1.首先我们要实现一个彩色方块 2.让色彩动 ...

  8. UnityShader快速上手指南(一)

    简介 引言 其实网上有很多shader教程,但是大概看了下,也不知是网上各位大神已经脱离了代码层面的高度还是啥原因.貌似没有找到从代码方面作为入门讲解的,导致了shader对于苦逼程序员入门有一定要求 ...

  9. Mac快速上手指南

    上周刚入手了2017版MacBookPro,预装macOS High Sierra.第一次接触Mac系统,经过一周的使用,简单总结下与Windows相比最常用的功能,快速上手. 1.Mac键盘实现Ho ...

随机推荐

  1. Edge 浏览器开发工具新增了 3D 视图,你尝试了吗?

    在使用开发者工具的时候,无意间发现了一个3D面板,如下: 仔细想想,这应该是之前 Firefox 的特性啊,不过后来去掉了,说是太难维护,没想到 Edge 也添加了这个特性. 使用该特性,你可以完成如 ...

  2. Spark中普通集合与RDD算子的sortBy()有什么区别

    分别观察一下集合与算子的sortBy()的参数列表 普通集合的sortBy() RDD算子的sortBy() 结论:普通集合的sortBy就没有false参数,也就是说只能默认的升序排. 如果需要对普 ...

  3. DFS 深搜专题 入门典例 -- 凌宸1642

    DFS 深搜专题 入门典例 -- 凌宸1642 深度优先搜索 是一种 枚举所有完整路径以遍历所有情况的搜索方法 ,使用 递归 可以很好的实现 深度优先搜索. 1 最大价值 题目描述 ​ 有 n 件物品 ...

  4. Macbook 安装kali linux 双系统 2020.3 超详细

    博主折腾了一星期这东西,到现在都还有些坑没解决(最后面会讲).不过最起码系统装上了,可以用了,看到这桌面惊艳了,再点下左上角表示人间值得. 其实我是装了windos 10.macos 和kali三系统 ...

  5. spring-cloud-stream消息驱动的微服务

    Spring Cloud Stream 是 一 个用来为微服务应用构建消息驱动能力的框架. 它可以基于Spring Boot 来创建独立的. 可用于生产的 Spring 应用程序. 它通过使用 Spr ...

  6. C语言-字符串函数的实现(一)之strlen

    C语言中的字符串函数有如下这些 获取字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数 strncpy strncat strncmp ...

  7. 为什么要进行系统拆分?如何进行系统拆分?拆分后不用dubbo可以吗?

    分布式系统,我用一句话给你解释一下,实在没时间多唠了,就是原来20万行代码的系统,现在拆分成20个小系统,每个小系统1万行代码.原本代码之间直接就是基于spring调用,现在拆分开来了,20个小系统部 ...

  8. ret2dl32

    ret2dl32 首先检查一下保护: IDA分析一下 程序很简单就是,往bss段上的buf读入0x400个数据,然后拷贝到栈上.read_got还被置为0,这一看就是要逼着你使用ret2dlresol ...

  9. Oracle-DG最大保护模式下,dg备库出现问题对主库有什么影响?

    一.需求 疑问?Oracle最大保护模式下,dg备库出现问题,影响主库吗? 我们都知道Oracle最大保护模式的意思是oracle不允许数据丢失,1条记录都不行! 那么备库有问题? oracle主库还 ...

  10. 如何使用natapp来实现内网穿透及案例

    1. 业务场景 当我们的项目是部署在本地的时候,如何让其他用户(不在同一个局域网之下)来进行调用呢?这时我们就可以使用内网穿透将自己的IP通过映射成相应的地址,然后再通过映射后的地址来进行访问本地的项 ...