准备工作

blazor wasm正式版发布了!在尝试使用的过程中,发现几个小坑,跟大家分享一下,希望有所帮助。

我是通过keycloak来保护blazor和service的,如何保护service请参考我之前的随笔,此处不再重复说明。

启动一个新的wasm项目,包含身份认证,但不是hosted(web前端和service在同一个网址),也就是最常见的web和service分别开发和分别部署的场景,使用如下命令新建项目:

dotnet new blazorwasm -o {存放路径} --au Individual

自动生成客户端代码

由于我的service采用了openapi,因此在wasm项目中,可以借助openapi代码生成工具,自动生成客户端代码,节约开发时间。这个步骤不是必须的,但是个人建议这样做。

首先,如果没有安装工具,先安装工具:

dotnet tool install -g microsoft.dotnet-openapi

然后,运行命令生成客户端代码:

dotnet openapi add url http://localhost:5000/swagger/v1/swagger.json --output-file Weather.json

以上工具只是将json文件注册到项目中,项目中还必须安装NSWag.CodeGeneration.CSharp,才能正常生成客户端代码,为了方便大家参考,将所有需要引用的包都写在这儿了。

<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="3.2.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.4" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NSwag.ApiDescription.Client" Version="13.0.5" />
<PackageReference Include="NSwag.CodeGeneration.CSharp" Version="13.5.0" />
<PackageReference Include="System.Net.Http.Json" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<OpenApiReference Include="Weather.json" SourceUrl="http://localhost:5000/swagger/v1/swagger.json" />
</ItemGroup>
</Project>

为了保证代码能够顺利生成,可以运行dotnet build命令,如果成功,Obj目录会出现一个WeatherClient.cs文件,其中包含了model和service。因为他使用了Newtonsoft.Json,所以要添加这个包的引用。

配置oidc

模板包含了oidc的基本配置,修改配置文件中的地址和客户端名称即可连接到openid服务。

实际操作中遇到几个坑:

  1. 无法获得access token或者json解析错误
  2. 无法获得用户名
  3. 访问service时,无法自动添加acess token到请求头部

无法获得access token

主要是app默认采用implicit认证流程,keycloak默认没有开启该流程,而且开启后,会无法解析json。

解决方法,修改program.cs,在builder.Services.AddOidcAuthentication中添加如下代码

options.ProviderOptions.ResponseType = "code";
修改认证流程为标准流程。

无法获得用户名

keycloak使用preferred_username发送用户名信息,而.net默认需要name字段,两边不匹配。

解决方法,要么修改这边,要么修改那边。

方法1:修改keycloak的client scopes - profile - mappers - username,修改"Token Claim Name"的内容为"name"

方法2:在builder.Services.AddOidcAuthentication中添加如下代码

options.UserOptions.NameClaim = "preferred_username";

访问service时,无法自动添加acess token到请求头部

这是最大的一个坑。

官方模板和文档中,总是在说如何访问自己hosted的service,但是实际使用中,app和service往往在不同的服务器上,官方文档最这种情况作了说明,但是如果不很细致的看文档,就容易理解错。

最主要的一点就是:BaseAddressAuthorizationMessageHandler只能给本地地址的请求加token,并不能处理不同服务器的情况。

下面是我的解决方法:

 var clientName = "BlazorWithIdentity.ServerAPI";
var baseUrl = builder.Configuration.GetValue<string>("ApiBaseUrl"); builder.Services.AddHttpClient(clientName, client => client.BaseAddress = new Uri(baseUrl))
.AddHttpMessageHandler(sp => sp.GetRequiredService<AuthorizationMessageHandler>()
.ConfigureHandler(new [] { baseUrl })); builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>()
.CreateClient(clientName)); builder.Services.AddTransient<WeatherClient>(s =>
new WeatherClient(null, s.GetRequiredService<IHttpClientFactory>().CreateClient(clientName)));

4行:注入名称为clientName的客户端,并且设置handler,对于来自baseUrl的所有请求自动添加Auth头;

8行:注入HttpClient,在页面上通过 @inject HttpClient Http,就可以使用自带Auth头部的HttpClient了;

11行:注入自动生成的WeatherClient,使用4行的HttpClient

页面调用service访问数据

经过前面的各种配置,页面访问数据就很简单了,如下:

@page "/fetchdata"
@using Microsoft.AspNetCore.Authorization
@inject WeatherClient Client
@attribute [Authorize] <h1>Weather forecast</h1> <p>This component demonstrates fetching data from the server.</p> @if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
} @code {
private IEnumerable<WeatherForecast> forecasts; protected override async Task OnInitializedAsync()
{
forecasts = await Client.WeatherForecastAsync();
}
}

怎么样,是不是很简洁的代码?

blazor wasm访问非本地的restful service的更多相关文章

  1. 测试必须学spring RESTful Service(上)

    文末我会说说为什么测试必须学spring. REST REST,是指REpresentational State Transfer,有个精辟的解释什么是RESTful, 看url就知道要什么 看met ...

  2. spring如何创建RESTful Service

    REST REST,是指REpresentational State Transfer,有个精辟的解释什么是RESTful, 看url就知道要什么 看method就知道干什么 看status code ...

  3. JAVA格物致知基础篇:用JAX-RS和Jersey打造RESTful Service

    随着服务器的处理能力越来越强,业务需求量的不断累积,越来越多的公司开始从单一服务器,单一业务承载变成了多服务器,多业务承载的快速扩展的过程中.传统的方法很难满足和应付这种业务量的增长和部署方式的改变. ...

  4. C# 服务端篇之实现RestFul Service开发(简单实用)

    一.RestFul简介 REST(Representational State Transfer 通常被翻译为“表述性状态传输”或者“表述性状态转移”)是RoyFielding提出的一个描述互联系统架 ...

  5. 使用Docker发布blazor wasm

    Blazor编译后的文件是静态文件,所以我们只需要一个支持静态页面的web server即可. 根据不同项目,会用不同的容器编排,本文已无网关的情况下为例,一步一步展示如何打包进docker 需求 H ...

  6. blazor wasm开发chrome插件

    用blazor(Wasm)开发了一个chrome插件感觉效率挺高的,分享给大家 先简单介绍下WebAssembly的原理: "WebAssembly是一种用于基于堆栈的虚拟机的二进制指令格式 ...

  7. 在IIS8.5的环境下配置WCF的Restful Service

    今天在客户的环境中(Windows Server 2012 R2 + IIS 8.5)搭建Call WCF Restful Service的功能,发现了几个环境配置的问题,记录如下: 1):此环境先安 ...

  8. 构建基于WCF Restful Service的服务

    前言 传统的Asmx服务,由于遵循SOAP协议,所以返回内容以xml方式组织.并且客户端需要添加服务端引用才能使用(虽然看到网络上已经提供了这方面的Dynamic Proxy,但是没有这种方式简便), ...

  9. Wcf Restful Service服务搭建

    目的 使用Wcf(C#)搭建一个Restful Service 背景 最近接到一个项目,客户要求使用Restful 方式接收到数据,并对数据提供对数据的统计显示功能,简单是简单,但必须要使用Restf ...

随机推荐

  1. Unity 极简UI框架

    写ui的时候一般追求控制逻辑和显示逻辑分离,经典的类似于MVC,其余大多都是这个模式的衍生,实际上书写的时候M是在整个游戏的底层,我更倾向于将它称之为D(Data)而不是M(Model),而C(Ctr ...

  2. OSG加载倾斜摄影数据

    目录 1. 概述 2. 实例 2.1. 代码 2.2. 解析 3. 结果 1. 概述 ContextCapture(Smart3D)生成的倾斜摄影模型数据一般都形如如下组织结构: 在Data目录下包含 ...

  3. latex-列表环境

    介绍 latex 主要有三种列表环境,进行罗列的实现, 无序列表 -- itemize 有序列表 -- enumerate 描述列表 -- description 本文进行了一一介绍和演示, 同时添加 ...

  4. 小米Note 10 Lite海外发布 无缘中国市场

    [TechWeb]5月1日消息,昨日晚间,小米Note 10 Lite在海外亮相.小米市场部副总经理臧智渊在微博透露,小米Note 10 Lite 6GB+64GB版售价349欧元(约合人民币2700 ...

  5. qcow2快照原理

    关键术语:cluster 一个Qcow2 img文件由固定大小的单元组成,该单元称为cluster,默认大小为65536bytes/64Ksector 数据块读写的最小单元,大小为512字节host ...

  6. 8种MySQL分页方法总结

    这篇文章主要介绍了8种MySQL分页方法总结,小编现在才知道,MySQL分页竟然有8种实现方法,本文就一一讲解了这些方法,需要的朋友可以参考下 MySQL的分页似乎一直是个问题,有什么优化方法吗?网上 ...

  7. 网课应该这么刷(油猴Tampermonkey脚本自动刷课)

    懒人福利 首先有些人不想学怎么用脚本,满足你们,压缩包解压之后直接登录即可.戳我下载 脚本已经集成好了,登录即可刷课.章节测试还会自动答题呦,正确率高达97%呦. 油猴及脚本安装 油猴的脚本不知可以刷 ...

  8. django最全面的知识点,直接开发完整手机购物商城练手,

    带手机验证码登陆, 带全套购物车系统 带数据库 前后端分离开发 带定位用户功能 数据库代码为本地制作好了 带支付宝支付系统 带django开发服务器接口教程 地址: https://www.duans ...

  9. andorid jar/库源码解析之EventBus

    目录:andorid jar/库源码解析 EventBus: 作用: 用于不同Activity,Service等之间传递消息(数据). 栗子: A页面:onCreate定义   EventBus.ge ...

  10. C. Anton and Fairy Tale(数学推式子)

    \(数学题,式子并不难推,但边界是真的烦\) \(\color{Red}{Ⅰ.其实可以发现,当m>=n时,每次都可以粮食补到n,所以一定是在第n天消耗完毕}\) \(\color{Purple} ...