Blazor SSR/WASM IDS/OIDC 单点登录授权实例5 - Winform 端授权
目录:
- OpenID 与 OAuth2 基础知识
- Blazor wasm Google 登录
- Blazor wasm Gitee 码云登录
- Blazor SSR/WASM IDS/OIDC 单点登录授权实例1-建立和配置IDS身份验证服务
- Blazor SSR/WASM IDS/OIDC 单点登录授权实例2-登录信息组件wasm
- Blazor SSR/WASM IDS/OIDC 单点登录授权实例3-服务端管理组件
- Blazor SSR/WASM IDS/OIDC 单点登录授权实例4 - 部署服务端/独立WASM端授权
- Blazor SSR/WASM IDS/OIDC 单点登录授权实例5 - Blazor hybird app 端授权
- Blazor SSR/WASM IDS/OIDC 单点登录授权实例5 - Winform 端授权
源码
建立winform项目
安装包 IdentityModel.OidcClient 以及 Microsoft.Web.WebView2 , 项目使用x64运行
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="IdentityModel.OidcClient" Version="5.2.1" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2210.55" />
</ItemGroup>
</Project>
拖放一个TextBox控件

Form1.cs 代码
using IdentityModel.OidcClient;
using System.Text;
using WinFormsWebView2;
namespace WinFormsOIDC;
public partial class Form1 : Form
{
static string authority = "https://localhost:5001/";
//static string authority = "https://ids2.app1.es/"; //真实环境
static string api = $"{authority}WeatherForecast";
static string clientId = "Blazor5002";
OidcClient _oidcClient;
public Form1()
{
InitializeComponent();
string redirectUri = string.Format($"http://localhost/authentication/login-callback");
string redirectLogoutUri = string.Format($"http://localhost/authentication/logout-callback");
var options = new OidcClientOptions
{
Authority = authority,
ClientId = clientId,
RedirectUri = redirectUri,
PostLogoutRedirectUri = redirectLogoutUri,
Scope = "BlazorWasmIdentity.ServerAPI openid profile",
Browser = new WinFormsWebView()
};
_oidcClient = new OidcClient(options);
Login();
}
private async void Login()
{
LoginResult loginResult;
try
{
loginResult = await _oidcClient.LoginAsync();
}
catch (Exception exception)
{
Output.Text = $"Unexpected Error: {exception.Message}";
return;
}
if (loginResult.IsError)
{
MessageBox.Show(this, loginResult.Error, "Login", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
var sb = new StringBuilder(128);
foreach (var claim in loginResult.User.Claims)
{
sb.AppendLine($"{claim.Type}: {claim.Value}");
}
if (!string.IsNullOrWhiteSpace(loginResult.RefreshToken))
{
sb.AppendLine();
sb.AppendLine($"refresh token: {loginResult.RefreshToken}");
}
if (!string.IsNullOrWhiteSpace(loginResult.IdentityToken))
{
sb.AppendLine();
sb.AppendLine($"identity token: {loginResult.IdentityToken}");
}
if (!string.IsNullOrWhiteSpace(loginResult.AccessToken))
{
sb.AppendLine();
sb.AppendLine($"access token: {loginResult.AccessToken}");
}
Output.Text = sb.ToString();
}
}
}
添加一个类 WinFormsWebView.cs
代码
using IdentityModel.OidcClient.Browser;
using Microsoft.Web.WebView2.WinForms;
namespace WinFormsWebView2;
public class WinFormsWebView : IBrowser
{
private readonly Func<Form> _formFactory;
private BrowserOptions? _options;
public WinFormsWebView(Func<Form> formFactory)
{
_formFactory = formFactory;
}
public WinFormsWebView(string title = "Authenticating ...", int width = 1024, int height = 768)
: this(() => new Form
{
Name = "WebAuthentication",
Text = title,
Width = width,
Height = height
})
{ }
public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken token = default)
{
_options = options;
using (var form = _formFactory.Invoke())
{
using (var webView = new WebView2()
{
Dock = DockStyle.Fill
})
{
var signal = new SemaphoreSlim(0, 1);
var browserResult = new BrowserResult
{
ResultType = BrowserResultType.UserCancel
};
form.FormClosed += (o, e) =>
{
signal.Release();
};
webView.NavigationStarting += (s, e) =>
{
if (IsBrowserNavigatingToRedirectUri(new Uri(e.Uri)))
{
e.Cancel = true;
browserResult = new BrowserResult()
{
ResultType = BrowserResultType.Success,
Response = new Uri(e.Uri).AbsoluteUri
};
signal.Release();
form.Close();
}
};
try
{
form.Controls.Add(webView);
webView.Show();
form.Show();
// Initialization
await webView.EnsureCoreWebView2Async(null);
// 删除现有的 Cookie,这样以前的登录就不会被记住, 以免影响测试, 反之去掉这行,就可以保持登录
//webView.CoreWebView2.CookieManager.DeleteAllCookies();
// Navigate
webView.CoreWebView2.Navigate(_options.StartUrl);
await signal.WaitAsync();
}
finally
{
form.Hide();
webView.Hide();
}
return browserResult;
}
}
}
private bool IsBrowserNavigatingToRedirectUri(Uri uri)
{
return uri.AbsoluteUri.StartsWith(_options?.EndUrl);
}
}
Enjoy!

Blazor SSR/WASM IDS/OIDC 单点登录授权实例5 - Winform 端授权的更多相关文章
- 如何基于Security实现OIDC单点登录?
一.说明 本文主要是给大家介绍 OIDC 的核心概念以及如何通过对 Spring Security 的授权码模式进行扩展来实现 OIDC 的单点登录. OIDC 是 OpenID Connect 的简 ...
- CAS单点登录(SSO)服务端的部署和配置---连接MySQL进行身份认证
一.修改系统host,加入 127.0.0.1 server.test.com127.0.0.1 client1.test.com127.0.0.1 client2.test.com 二.安装grad ...
- shiro 单点登录原理 实例
原创 2017年02月08日 17:39:55 4006 Shiro 1.2开始提供了Jasig CAS单点登录的支持,单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即 ...
- UCenter在JAVA项目中实现的单点登录应用实例
Comsenz(康盛)的UCenter当前在国内的单点登录领域占据绝对份额,其完整的产品线令UCenter成为了账号集成方面事实上的标准. 基于UCenter,可以将Comsenz旗下的Discuz! ...
- SSO单点登录系列3:cas-server端配置认证方式实践(数据源+自定义java类认证)
落雨 cas 单点登录 本篇将讲解cas-server端的认证方式 1.最简单的认证,用户名和密码一致就登录成功 2.配置Oracle的jdbc数据源,通过spring动态查询数据库 3.配置orac ...
- Java--实现单点登录
1 什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用 ...
- 单点登录SSO的实现原理 (转)
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得 ...
- 点单登录原理和java实现简单的单点登录
引用自:http://blog.csdn.net/zuoluoboy/article/details/12851725 摘要: 单点登录(SSO)的技术被越来越广泛地应用到各个领域的软件系统当中.本文 ...
- 单点登录SSO
转载自 http://www.blogjava.net/xcp/archive/2010/04/13/318125.html 摘要:单点登录(SSO)的技术被越来越广泛地运用到各个领域的软件系统当 ...
- 编写你自己的单点登录(SSO)服务
王昱 yuwang881@gmail.com 博客地址http://yuwang881.blog.sohu.com 摘要:单点登录(SSO)的技术被越来越广泛地运用到各个领域的软件系统其中.本文从 ...
随机推荐
- Python趣味入门12:初遇类与实例
小牛叔用轻松有趣的故事,带你进入Python的编程世界. 1.类 一提到类大神们就经常说封装.说白了,封装即把围绕同一个对象相同的代码.数据整合在一起.比如在某段游戏代码中(比如熊猫厨房),有一个&q ...
- 【JVM】一文掌握JVM垃圾回收机制
作为Java程序员,除了业务逻辑以外,随着更深入的了解,都无法避免的会接触到JVM以及垃圾回收相关知识.JVM调优是一个听起来很可怕,实际上很简单的事. 感到可怕,是因为垃圾回收相关机制都在JVM的C ...
- 【scikit-learn基础】--『监督学习』之 随机森林回归
随机森林回归(Random Forest Regression)是一种在机器学习领域广泛应用的算法,由美国科学家 Leo Breiman 在2001年提出.它是一种集成学习方法,通过整合多个决策树的预 ...
- MongoDB的CRUD操作(入门)
MongoDB的简单介绍: 1:MongoDB是什么? mongodb是非关系数据库 但是是非关系数据库当中功能最丰富,最像关系数据库的 MongoDB是一个基于分布式文件存储的数据库. 由C++语言 ...
- JVM优化:如何进行JVM调优,JVM调优参数有哪些
Java虚拟机(JVM)是Java应用运行的核心环境.JVM的性能优化对于提高应用性能.减少资源消耗和提升系统稳定性至关重要.本文将深入探讨JVM的调优方法和相关参数,以帮助开发者和系统管理员有效地优 ...
- 文心一言 VS 讯飞星火 VS chatgpt (22)-- 算法导论4.2 2题
二.为Strassen算法编写伪代码. 文心一言: Strassen算法是一种用于矩阵乘法的算法,它的核心思想是通过不断将原始矩阵分割成较小的子矩阵来实现高效的乘法运算.以下是Strassen算法的伪 ...
- 神经网络基础篇:详解logistic 损失函数(Explanation of logistic regression cost function)
详解 logistic 损失函数 在本篇博客中,将给出一个简洁的证明来说明逻辑回归的损失函数为什么是这种形式. 回想一下,在逻辑回归中,需要预测的结果\(\hat{y}\),可以表示为\(\hat{y ...
- 加快云原生技术转型, 智能调度登陆华为云DevOps: 增速,节源
摘要:本文将探讨智能资源调度在华为云DevOps上的应用与实践. 本文分享自华为云社区<加快云原生技术转型, 智能调度登陆华为云DevOps: 增速,节源>,作者: DevAI. 1. 背 ...
- 测试用例又双叒叕失败了,NLP帮你
摘要:本文将介绍如何使用AI技术实现失败测试用例的智能分析. 本文分享自华为云社区<测试用例又双叒叕失败了,啥原因?NLP帮你来分析>,作者: 敏捷的小智 . 随着软件行业的快速发展,为了 ...
- 云小课 | SA基线检查—给云服务的一次全面“体检”
阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要: 华为云态势感知( ...