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)的技术被越来越广泛地运用到各个领域的软件系统其中.本文从 ...
随机推荐
- dtd的三种引入方式
- cache操作:clean、invalidate与flush的含义
前言 本文试图搞清楚cache几个操作:clean.invalidate与flush的含义.由于只用过ARM和RISC-V,所以是从ARM和RISC-V的角度来说明. cache line cache ...
- ESXi6.7物理机安装之网卡驱动封装Realtek PCIe GBE Family Controller =瑞昱r8168网卡驱动
https://blog.whsir.com/post-3423.html "我这里先提供一个ESXI6.5封装好的r8168网卡驱动ESXI6.5u2.iso,如果你的网卡也是这个,可以直 ...
- Pikachu漏洞靶场 RCE(远程命令执行/代码执行)
RCE 文章目录 RCE 概述 exec "ping" exec "eval" 概述 RCE(remote command/code execute),远程命令 ...
- Odoo16—级联删除
我们在odoo中构建业务系统模块的时候,通常会使用one2many.many2one或many2many将模型进行关联,由此产生的数据也会通过外键发生关联.那么在odoo中删除数据的时候,如何关联删除 ...
- Spring源码学习笔记6——Spring bean的实例化
一丶前言 前面我们了解到读取xml or 根据扫描路径生成BeanDefinition并注册到BeanFactory,相当于我们具备了生火做饭的原材料:BeanDefinition,接下来就是Spri ...
- Asp .Net Core 系列:基于 Swashbuckle.AspNetCore 包 集成 Swagger
什么是 Swagger? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.它提供了一种规范的方式来定义.构建和文档化 RESTful Web ...
- 在Docker上面安装/启动、运行、挂载MySQL5.7
下载文档请看:https://hub.docker.com/r/mysql/mysql-server 一.下载镜像 执行命令: docker pull mysql/mysql-server:5.7 查 ...
- LeetCode1两数之和、15三数之和
1. 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组中同一个元素 ...
- 华为云API Explorer重磅推出API编排,开发者0代码高效构建工作流
本文分享自华为云社区<华为云API Explorer重磅推出API编排,开发者0代码高效构建工作流(体验用户招募中)>,作者:华为云PaaS服务小智. 打破传统开发模式,API编排应运而生 ...