Table of Contents
实现登陆认证方式
在同一个一级域名下有很二级域名系统,如:https://www.iaspnetcore.com/, https://search.iaspnetcore.com 等.
但是这些系统都是www.iaspnetcore.com的二级域。
要实现上述功能,首先要了解一个网站有哪些认证登陆方式。Asp .Net Core的认证有很多方式可以实现,如:cookie认证,jwt认证等等。我把它精简一下,从浏览器和服务器之间的认证信息载体的传递的角度,其实只有两种方式可以选择:
1.使用cookie方式实现登陆认证:
浏览器和服务器之间的认证信息传递,用cookie。系统自带的认证方式,最常用的一种。
2.使用token方式实现登陆认证:
如jwt,IdentityServer等,都是基于token在浏览器和服务器如何认证、传递的实现方案。
本次采用cookie方式实现登陆认证。这样的情况就可以在不引用其它框架的情况下,直接基于Cookie实现同域单点登录SSO(Single Sign-on)
使用cookie方式实现登陆认证要实现的功能
实现一个系统登录,其它子系统都登录。一个子系统退出。其它子系统也都退出的功能.
同一主域名下二级域名web服务单点登录SSO的实现的条件
要实现上述目的,需要做到以下几点:
1.所有的站点都要使用同一个cookie
2.所有的站点都要使用同一种对cookie的加密、解密方式
3.所有的站点都要使用同一种程序名AplicationName
cookie登陆过程
在一个Web应用程序中,通常使用一个cookie来表示一个已经登录的用户。
一般的流程是:
1.用户单击登录,进入登录页面。
2.输入有效凭证后(用户名和用户密码),服务器发送给用户浏览器的响应头包含一个带 Set-Cookie 头,其内容为加密信息。
3.被设置上domain 例如 giant.com,每次浏览器向这个domain发送请求时,设置在这个domain上的cookie也会被带上。
options.Cookie.Domain = ".example.com";
should be your cookie domain
the dot . ensure that its a shared cookie in domain
4.在服务器上,cookie将被解密,然后使用解密后的内容来创建用户的 Identity。
实现思路
1.发送同一个cookie:浏览器浏览不同的站点时,要让浏览器向web服务站点发送同一个cookie,这个只要把 CookieDomain设置为根域名就可达到让浏览器访问不同子域名时发送同一个cookie。如:CookieDomain=".iaspnetcore.com",
2.所有站点都使用同一种数据解密方式:这个需要把数据保护配置到同一个地方,同一主域名下所有的网站都都使用同一中数据解密方式。如:
services.AddDataProtection()
.SetApplicationName("isapnetcore")
.PersistKeysToFileSystem(new DirectoryInfo(keysFolder));
实现方法
1.修改配置主要统一数据加密方式与统一应用名称
这样其它子域的Cookie加密数据就能识别。
2.配置统一的Cookie名称与写的域名为根域。
这样所有子域都能发现与识别此登录的Cookie信息
3.这样就可以实现一个系统登录,其它子系统都登录
一个子系统退出。其它子系统也都退出的功能
添加需要的引用:
path:\Startup.cs
using System.Runtime.InteropServices;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Authentication.Cookies;
Startup代码:
添加引用 using Microsoft.AspNetCore.DataProtection,services.AddDataProtection()要用到。添加如下代码:
public void ConfigureServices(IServiceCollection services)
{
#region 配置数据保护,Preventing Cross-Site Request Forgery (XSRF/CSRF) Attacks in ASP.NET Core
//https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-3.1
var keysFolder = "";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
keysFolder = "C:\\artifacts";
else
keysFolder = "/var/share/ ";
services.AddDataProtection()
.SetApplicationName("isapnetcore")
.PersistKeysToFileSystem(new DirectoryInfo(keysFolder));
#endregion
}
登录代码
public async void Login() { if (!HttpContext.User.Identities.Any(identity => identity.IsAuthenticated)) { var user = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "bob") }, CookieAuthenticationDefaults.AuthenticationScheme)); await HttpContext.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user); HttpContext.Response.ContentType = "text/plain"; await HttpContext.Response.WriteAsync("Hello First timer"); } else { HttpContext.Response.ContentType = "text/plain"; await HttpContext.Response.WriteAsync("Hello old timer"); } }
注意
C:\keys\key.xml 这个文件路径可以更改,还有就是也可用共享目录或数据库来实现统一管理
到此可以登录试一下。