Blazor OIDC 单点登录授权实例5 - 独立SSR App (net8 webapp ) 端授权
目录:
- OpenID 与 OAuth2 基础知识
- Blazor wasm Google 登录
- Blazor wasm Gitee 码云登录
- Blazor OIDC 单点登录授权实例1-建立和配置IDS身份验证服务
- Blazor OIDC 单点登录授权实例2-登录信息组件wasm
- Blazor OIDC 单点登录授权实例3-服务端管理组件
- Blazor OIDC 单点登录授权实例4 - 部署服务端/独立WASM端授权
- Blazor OIDC 单点登录授权实例5 - 独立SSR App (net8 webapp)端授权
- Blazor OIDC 单点登录授权实例6 - Winform 端授权
- Blazor OIDC 单点登录授权实例7 - Blazor hybird app 端授权
(目录暂时不更新,跟随合集标题往下走)
源码
十分钟搞定单点登录
单点登录(SSO)简化了用户体验,使用户能够在访问多个应用时只需一次登录。这提高了用户满意度,减少了密码遗忘的风险,同时增强了安全性。但是,实现单点登录并不容易,需要应用程序实现和认证服务器的交互逻辑,增加了应用程序的开发工作量。例子中的安全策略中提供了 OpenID Connect (OIDC) 的能力,无需对应用做过多的修改,在十分钟内即可立刻实现单点登录。
当采用单点登录之后,用户只需要登录一次,就可以访问多个应用系统。SSO 通常由一个独立的身份管理系统来完成,该系统为每个用户分配一个全局唯一的标识,用户在登录时,只需要提供一次身份认证,就可以访问所有的应用系统。我们在使用一些网站时,经常会看到“使用微信登录”、“使用 Google 账户登录”等按钮,这些网站就是通过 SSO 来实现的。
采用单点登录有以下几个好处:
用户只需要登录一次,就可以访问多个应用系统,不需要为每个应用系统都单独登录。
应用系统不需要自己实现用户认证,只需将认证工作交给单点登录系统,可以大大减少应用系统的开发工作量。
使用 OIDC 单点登录, 可以简化客户端编写流程, 专注于功能实现而不用重复撰写登录部分功能代码, 也不用直接接触身份验证数据库, 剥离繁琐的重复劳动部分.
建立 net8 webapp ssr 工程

引用以下库
<ItemGroup>
<PackageReference Include="BootstrapBlazor" Version="8.*" />
<PackageReference Include="Densen.Extensions.BootstrapBlazor" Version="8.*" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.*" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.*" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.*" />
</ItemGroup>
_Imports.razor 加入引用
@using BootstrapBlazor.Components
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
App.razor 加入必须的UI库引用代码
完整文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<Link Href="_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css" />
<Link Href="_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css" />
<Link Href="_content/BootstrapBlazor/css/motronic.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="BlazorSSRAppOIDC.styles.css" />
<HeadOutlet @rendermode="new InteractiveServerRenderMode(false)" />
</head>
<body>
<Routes @rendermode="new InteractiveServerRenderMode(false)" />
<ReconnectorOutlet ReconnectInterval="5000" @rendermode="new InteractiveServerRenderMode(false)" />
<Script Src="_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js"></Script>
<script src="_framework/blazor.web.js"></script>
</body>
</html>
Routes.razor 加入授权
完整代码
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)">
<NotAuthorized>
<p role="alert">您无权访问该资源.</p>
</NotAuthorized>
<Authorizing>
<p>正在验证您的身份...</p>
</Authorizing>
</AuthorizeRouteView>
</Found>
</Router>
添加Oidc授权配置

新建 OidcProfile.cs 文件
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using System.Security.Claims;
namespace OidcClientShared;
public class OidcProfile
{
public static void OidcDIY(OpenIdConnectOptions options)
{
var authority = "https://ids2.app1.es/"; //由于时间的关系,已经部署有一个实际站点, 大家也可以参考往期文章使用本机服务器测试
//authority = "https://localhost:5001/";
var clientId = "Blazor5002";
var callbackEndPoint = "http://localhost:5002";
options.Authority = authority;
options.ClientId = clientId;
options.ResponseType = OpenIdConnectResponseType.Code;
options.ResponseMode = OpenIdConnectResponseMode.Query;
options.SignedOutRedirectUri = callbackEndPoint;
options.CallbackPath = "/authentication/login-callback";
options.SignedOutCallbackPath = "/authentication/logout-callback";
options.Scope.Add("BlazorWasmIdentity.ServerAPI openid profile");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.MapInboundClaims = false;
options.ClaimActions.MapAll();
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
options.ClaimActions.MapJsonKey(ClaimValueTypes.Email, "email", ClaimValueTypes.Email);
options.ClaimActions.MapJsonKey(ClaimTypes.Role, "role");
options.Events = new OpenIdConnectEvents
{
OnAccessDenied = context =>
{
context.HandleResponse();
context.Response.Redirect("/");
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
var token = context.TokenEndpointResponse?.AccessToken;
if (!string.IsNullOrEmpty(token))
{
if (context.Principal?.Identity != null)
{
var identity = context.Principal!.Identity as ClaimsIdentity;
identity!.AddClaim(new Claim("AccessToken", token));
}
}
return Task.CompletedTask;
}
};
}
}
Program.cs 加入授权相关
其中要加入Razor的cshtml支持, 因为登录要依靠管道跳转. 上下有两行都注释在文件内了.
完整代码
using BlazorSSRAppOIDC.Components;
using OidcClientShared;
var builder = WebApplication.CreateBuilder(args);
//在具有 Blazor Web 应用程序模板的 .NET 8 中,需要将其更改为, 由于该Pages文件夹已移至该Components文件夹中,因此您需要指定新位置的根目录,或将该Pages文件夹移回项目的根级别
builder.Services.AddRazorPages().WithRazorPagesRoot("/Components/Pages");
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddHttpClient();
builder.Services.AddDensenExtensions();
builder.Services.ConfigureJsonLocalizationOptions(op =>
{
// 忽略文化信息丢失日志
op.IgnoreLocalizerMissing = true;
});
builder.Services
.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", OidcProfile.OidcDIY);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery();
//但出于某种原因,这还不够。在 Blazor Web 应用程序模板中,您明确需要调用
app.MapRazorPages();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();
Pages 文件夹新建登录Razor页实现登录和注销跳转

展开 Login.cshtml 文件组合三角箭头, 编辑 Login.cshtml.cs

Login.cshtml.cs
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace PersonalToolKit.Server.Components.Pages;
public class LoginModel : PageModel
{
public async Task OnGet(string redirectUri)
{
await HttpContext.ChallengeAsync("oidc", new AuthenticationProperties { RedirectUri = redirectUri });
}
}
Logout.cshtml.cs
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace PersonalToolKit.Server.Components.Pages;
public class LogoutModel : PageModel
{
public async Task OnGet(string redirectUri)
{
await HttpContext.SignOutAsync("Cookies");
await HttpContext.SignOutAsync("oidc", new AuthenticationProperties { RedirectUri = redirectUri });
}
}
Routes.razor 加入授权
完整代码
Home.razor
完整代码
@page "/"
@using System.Security.Claims
@inject NavigationManager Navigation
<PageTitle>Home</PageTitle>
<AuthorizeView>
<Authorized>
你好, @context.User.Identity?.Name (@context.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Role)?.Value)
<Button Text="注销" OnClick="BeginLogOut" />
<br /><br /><br />
<h5>以下是用户的声明</h5><br />
@foreach (var claim in context.User.Claims)
{
<p>@claim.Type: @claim.Value</p>
}
</Authorized>
<NotAuthorized>
<Button Text="登录" OnClick="BeginLogIn" />
<p>默认账号 test@test.com 密码 0</p>
</NotAuthorized>
</AuthorizeView>
@code {
private string LoginUrl = "login?redirectUri=";
private void BeginLogIn()
{
var returnUrl = Uri.EscapeDataString(Navigation.Uri);
Navigation.NavigateTo(LoginUrl + returnUrl, forceLoad: true);
}
private string LogoutUrl = "logout?redirectUri=";
private void BeginLogOut()
{
var returnUrl = Uri.EscapeDataString(Navigation.Uri);
Navigation.NavigateTo(LogoutUrl + returnUrl, forceLoad: true);
}
}
运行

Blazor OIDC 单点登录授权实例5 - 独立SSR App (net8 webapp ) 端授权的更多相关文章
- 如何基于Security实现OIDC单点登录?
一.说明 本文主要是给大家介绍 OIDC 的核心概念以及如何通过对 Spring Security 的授权码模式进行扩展来实现 OIDC 的单点登录. OIDC 是 OpenID Connect 的简 ...
- shiro 单点登录原理 实例
原创 2017年02月08日 17:39:55 4006 Shiro 1.2开始提供了Jasig CAS单点登录的支持,单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即 ...
- UCenter在JAVA项目中实现的单点登录应用实例
Comsenz(康盛)的UCenter当前在国内的单点登录领域占据绝对份额,其完整的产品线令UCenter成为了账号集成方面事实上的标准. 基于UCenter,可以将Comsenz旗下的Discuz! ...
- SSO 基于Cookie+fliter实现单点登录 实例解析(一)
接上文,SSO的理论讲解,接下来实践实践! 1.使用Cookie解决单点登录 技术点: 1.设置Cookie的路径为setPath("/").即Tomcat的目录下都有效 2.设置 ...
- java单点登录系统CAS的简单使用
转:http://blog.csdn.net/yunye114105/article/details/7997041 背景 有几个相对独立的java的web应用系统, 各自有自己的登陆验证功能,用户在 ...
- SSO 基于Cookie+fliter实现单点登录(SSO):工作原理
SSO的概念: 单点登录SSO(Single Sign-On)是身份管理中的一部分. SSO的一种较为通俗的定义是:SSO是指訪问同一server不同应用中的受保护资源的同一用户,仅仅须要登录一次,即 ...
- 基于CAS实现单点登录(SSO):工作原理
工作中使用到了SSO,网上看到了这个博客的一系列文章感觉不错,转载收藏 源地址http://blog.csdn.net/tch918/article/details/19930037 系列文章的第一篇 ...
- SSO单点登录思路
SSO (Single Sign On) 什么是单点登录: 在大型的互联网公司中会有多个系统, 多个项目, 虽然这些项目都属于同一家公司, 但是项目本身其实都是独立的, 那多个系统可不可以实现共享同一 ...
- 偷懒小工具 - SSO单点登录通用类(可跨域)
写在前面的话 上次发布过一篇同样标题的文章.但是因为跨域方面做得不太理想.我进行了修改,并重新分享给大家. 如果这篇文章对您有所帮助,请您点击一下推荐.以便有动力分享出更多的"偷懒小工具&q ...
- 网站跨站点单点登录实现--cookie
至于什么是单点登录,举个例子,如果你登录了msn messenger,访问hotmail邮件就不用在此登录.一般单点登录都需要有一个独立的登录站点,一般具有独立的域名,专门的进行注册,登录,注销等操作 ...
随机推荐
- 通过 Feign 进行文件上传
转载请注明出处: 项目为spring cloud 项目,项目中对各部分能力业务进行了拆分,将公共的服务能力放在一个模块当中,通过 Feign 的方式 进行调用,feign 调用的本质还是http内部通 ...
- linux 命令使用总结:vim,nohup,find,df,du,sudo,netstat,ll,curl,lastlog
1.Vim命令使用 vim 为编辑文本命令: vim 文件 回车即可查看文件 按 字母 i 键,即可进入 insert 编辑模式. 按 ESC 键即可退出编辑模式 输入冒号:wq 即可保存修改 输入 ...
- 【ThreadX-NetX】Azure RTOS NetX概述
Azure RTOS NetX是工业级TCP / IP IPv4嵌入式网络堆栈,专门针对深度嵌入式,实时和IoT应用程序而设计.Azure RTOS NetX是Microsoft最初的IPv4网络堆栈 ...
- 聊聊x86计算机启动发生的事?
大家好,我是呼噜噜,最近在看linux早期内核0.12的源码,突然想到一个困扰自己好久的问题:当我们按下电源键,计算机发生了什么?神秘地址0x7C00究竟是什么?操作系统又是如何被加载到硬件中的?带着 ...
- [转帖]Nginx 性能优化
目录 1.调整 worker 进程数 2.调整 worker 连接数 3.调整 work 进程最大打开文件数 4.开启高效文件传输模式 5.限制文件上传大小 6.开启 gzip 压缩 7.本地缓存静态 ...
- [转帖]为什么不推荐使用/etc/fstab
https://www.jianshu.com/p/af49a5d0553f 对于工作中使用服务器的公司来讲,每到节假日来临时,总免不了对服务器进行下电.而收假回来的早上,则会有一个早上的时间会花费在 ...
- [转帖]vs调试运行程序出现:“由于找不到MSVCP140D.dll,无法继续执行代码 ”的解决方法
碎碎念 最近在使用Visual studio调试程序的时候,突然冒出了"由于找不到MSVCP140D.dll,无法继续执行代码.重新安装程序可能会解决次问题."的错误.如下图所示. ...
- Python学习之十三_pip的学习
Python学习之十三_pip的学习 pip的含义 pip: pip is the package installer for Python. You can use pip to install p ...
- sringboot 调试端口启用的写法
注意 需要在 -jar 的后面加 加在前面貌似没用 $JAVA_HOME/bin/java -Dloader.path=$CAF_MODULE_PATHS -jar -Dspring.profiles ...
- Windows 2019 standard 安装 Sqlserver 2019 Standard 时报错 不知道如何处理
Microsoft Windows [版本 10.0.17763.1] (c) 2018 Microsoft Corporation.保留所有权利. D:\>setup.exe Microsof ...