<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>久爱编程网</title><link>https://www.9icode.com/</link><description>爱编程，爱技术，专注.NET/C#后端设计与开发！</description><item><title>使用HTTPS访问Wordpress站点的问题解决</title><link>https://www.9icode.com/index.php/post/395.html</link><description>&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;安装Wordpress后使用HTTPS访问，可能会出现页面错乱问题，在浏览器控制台显示类似如下错误提示：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;Blocked&amp;nbsp;loading&amp;nbsp;mixed&amp;nbsp;active&amp;nbsp;content&amp;nbsp;“http://9icode.com/wp-includes/css/dashicons.min.css?ver=6.3.1”
Blocked&amp;nbsp;loading&amp;nbsp;mixed&amp;nbsp;active&amp;nbsp;content&amp;nbsp;“http://9icode.com/wp-includes/css/admin-bar.min.css?ver=6.3.1”
Blocked&amp;nbsp;loading&amp;nbsp;mixed&amp;nbsp;active&amp;nbsp;content&amp;nbsp;“http://9icode.com/wp-includes/css/dist/block-library/style.min.css?ver=6.3.1”
Blocked&amp;nbsp;loading&amp;nbsp;mixed&amp;nbsp;active&amp;nbsp;content&amp;nbsp;“http://9icode.com/wp-content/themes/bloghash/assets/css/swiper-bundle.min.css?ver=6.3.1”
Blocked&amp;nbsp;loading&amp;nbsp;mixed&amp;nbsp;active&amp;nbsp;content&amp;nbsp;“http://9icode.com/wp-content/themes/bloghash/assets/css/all.min.css?ver=5.15.4”
Blocked&amp;nbsp;loading&amp;nbsp;mixed&amp;nbsp;active&amp;nbsp;content&amp;nbsp;“http://9icode.com/wp-content/themes/bloghash/assets/css/style.min.css?ver=1.0.25”
Blocked&amp;nbsp;loading&amp;nbsp;mixed&amp;nbsp;active&amp;nbsp;content&amp;nbsp;“http://9icode.com/wp-content/uploads/bloghash/dynamic-styles.css?ver=1761397781”
Blocked&amp;nbsp;loading&amp;nbsp;mixed&amp;nbsp;active&amp;nbsp;content&amp;nbsp;“http://9icode.com/wp-includes/js/jquery/jquery.min.js?ver=3.7.0”
Loading&amp;nbsp;failed&amp;nbsp;for&amp;nbsp;the&amp;nbsp;&amp;lt;script&amp;gt;&amp;nbsp;with&amp;nbsp;source&amp;nbsp;“http://en.9icode.com/wp-includes/js/jquery/jquery.min.js?ver=3.7.0”
Blocked&amp;nbsp;loading&amp;nbsp;mixed&amp;nbsp;active&amp;nbsp;content&amp;nbsp;“http://en.9icode.com/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.4.1”&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;原因是部分CSS和JS文件在HTTPS访问时，仍然是HTTP地址，由于浏览器的CSP策略，HTTPS不能HTTP资源，解决方案是在wp-config.php开头添加如下行：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-php&quot;&gt;define(&amp;#39;FORCE_SSL_ADMIN&amp;#39;,&amp;nbsp;true);
$_SERVER[&amp;#39;HTTPS&amp;#39;]&amp;nbsp;=&amp;nbsp;&amp;#39;on&amp;#39;;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;对于其它第三方插件的HTTPS问题可以安装“&lt;strong&gt;SSL Insecure Content Fixer&lt;/strong&gt;”，设置“Fix insecure content”为“Capture”、“Ignore external sites”为“Only fix content pointing to this WordPress site”、“HTTPS detection”为“HTTP_X_FORWARDED_PROTO (e.g. load balancer, reverse proxy, NginX)”。&lt;/p&gt;</description><pubDate>Wed, 19 Nov 2025 20:49:34 +0800</pubDate></item><item><title>如何安装pnpm</title><link>https://www.9icode.com/index.php/post/394.html</link><description>&lt;p&gt;1、安装NodeJS，NodeJS自带npm包管理器，且依赖Python；&lt;/p&gt;&lt;p&gt;2、在命令提示符、VSCode或PowerShell等终端中执行：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;npm&amp;nbsp;install&amp;nbsp;-g&amp;nbsp;pnpm&lt;/pre&gt;&lt;p&gt;3、若运行“pnpm install”提示无权限是因为PowerShell的执行策略限制，执行如下命令修改：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;Set-ExecutionPolicy&amp;nbsp;-ExecutionPolicy&amp;nbsp;RemoteSigned&lt;/pre&gt;&lt;p&gt;4、参考：&lt;a href=&quot;https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.5&quot; _src=&quot;https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.5&quot;&gt;https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.5&lt;/a&gt;&lt;/p&gt;&lt;p&gt;5、若执行pnpm install时提示找不到test命令，则打开package.json添加test命令：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;{
&amp;nbsp;&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;quot;scripts&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;i&amp;quot;:&amp;nbsp;&amp;quot;pnpm&amp;nbsp;install&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;dev&amp;quot;:&amp;nbsp;&amp;quot;pnpm&amp;nbsp;vite&amp;nbsp;--mode&amp;nbsp;base&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;test&amp;quot;:&amp;nbsp;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;...
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Mon, 10 Nov 2025 17:42:05 +0800</pubDate></item><item><title>使用了husky的Vue3项目在执行命令“pnpm install”时提示“husky - install command is DEPRECATED”问题解决</title><link>https://www.9icode.com/index.php/post/393.html</link><description>&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;在使用了husky的Vue3项目中，执行命令“pnpm install”时，若报如下错误：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;husky&amp;nbsp;-&amp;nbsp;install&amp;nbsp;command&amp;nbsp;is&amp;nbsp;DEPRECATED&lt;/pre&gt;&lt;p&gt;&amp;nbsp;是因为package.json中husky的安装命令已过时，改为最新安装命令即可：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;&amp;quot;prepare&amp;quot;:&amp;nbsp;&amp;quot;pnpm&amp;nbsp;dlx&amp;nbsp;husky-init&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;husky&amp;nbsp;install&amp;quot;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;若使用npm或yarn，可改为如下安装命令：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;&amp;quot;prepare&amp;quot;:&amp;nbsp;&amp;quot;npx&amp;nbsp;husky-init&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;husky&amp;nbsp;install&amp;quot;&lt;/pre&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &lt;code&gt;若在提交Git时提示找不到.husky/commit-msg等类似错误，但该文件确实存在则可能是权限问题，使用Git Bash打开&lt;code&gt;.husky&lt;/code&gt;所在目录，并赋予&lt;code&gt;commit-msg&lt;/code&gt;写入权限：&lt;/code&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;#&amp;nbsp;检查文件权限
ls&amp;nbsp;-la&amp;nbsp;.husky/commit-msg

#&amp;nbsp;如果没有执行权限，添加执行权限
chmod&amp;nbsp;+x&amp;nbsp;.husky/commit-msg

#&amp;nbsp;或者递归设置整个&amp;nbsp;.husky&amp;nbsp;目录的权限
chmod&amp;nbsp;-R&amp;nbsp;+x&amp;nbsp;.husky/&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Mon, 10 Nov 2025 17:34:48 +0800</pubDate></item><item><title>OpenIddict从零开始（三）——基于ASP.NET Core创建自定义服务端</title><link>https://www.9icode.com/index.php/post/392.html</link><description>&lt;p&gt;1、使用现有或新建一个&amp;quot;ASP.NET Core Empty&amp;quot;等相关类型的项目，在Nuget Package Manager中引用OpenIddict.AspNetCore、OpenIddict.EntityFrameworkCore两个Nuget包，或在*.csproj项目文件中新增如下行：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;ItemGroup&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;PackageReference&amp;nbsp;Include=&amp;quot;OpenIddict.AspNetCore&amp;quot;&amp;nbsp;Version=&amp;quot;7.1.0&amp;quot;&amp;nbsp;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;PackageReference&amp;nbsp;Include=&amp;quot;OpenIddict.EntityFrameworkCore&amp;quot;&amp;nbsp;Version=&amp;quot;7.1.0&amp;quot;&amp;nbsp;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/ItemGroup&amp;gt;&lt;/pre&gt;&lt;p&gt;OpenIddict.AspNetCore是OpenIddict的核心类库，OpenIddict.EntityFrameworkCore是OpenIddict的EF Core支持类库。&lt;/p&gt;&lt;p&gt;2、自定义一个OpenIddict注册相关类：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-csharp&quot;&gt;///&amp;nbsp;&amp;lt;summary&amp;gt;
///&amp;nbsp;
///&amp;nbsp;&amp;lt;/summary&amp;gt;
public&amp;nbsp;class&amp;nbsp;Shared
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;static&amp;nbsp;string&amp;nbsp;UnsupportedDatabaseTypeError&amp;nbsp;{&amp;nbsp;get;&amp;nbsp;set;&amp;nbsp;}&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;;
}

///&amp;nbsp;&amp;lt;summary&amp;gt;
///&amp;nbsp;OIDC&amp;nbsp;Options
///&amp;nbsp;&amp;lt;/summary&amp;gt;
public&amp;nbsp;class&amp;nbsp;OIDCOptions
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;Database&amp;nbsp;Type
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;string&amp;nbsp;DatabaseType&amp;nbsp;{&amp;nbsp;get;&amp;nbsp;set;&amp;nbsp;}&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;Connection&amp;nbsp;String
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;string&amp;nbsp;ConnectionString&amp;nbsp;{&amp;nbsp;get;&amp;nbsp;set;&amp;nbsp;}&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;Token&amp;nbsp;EndpointUris
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;string&amp;nbsp;TokenEndpointUris&amp;nbsp;{&amp;nbsp;get;&amp;nbsp;set;&amp;nbsp;}&amp;nbsp;=&amp;nbsp;&amp;quot;connect/token&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;Authorizatio&amp;nbsp;nEndpointUris
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;string&amp;nbsp;AuthorizationEndpointUris&amp;nbsp;{&amp;nbsp;get;&amp;nbsp;set;&amp;nbsp;}&amp;nbsp;=&amp;nbsp;&amp;quot;connect/authorize&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;UserInfo&amp;nbsp;EndpointUris
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;string&amp;nbsp;UserInfoEndpointUris&amp;nbsp;{&amp;nbsp;get;&amp;nbsp;set;&amp;nbsp;}&amp;nbsp;=&amp;nbsp;&amp;quot;connect/userinfo&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;EndSession&amp;nbsp;EndpointUri
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;string&amp;nbsp;EndSessionEndpointUri&amp;nbsp;{&amp;nbsp;get;&amp;nbsp;set;&amp;nbsp;}&amp;nbsp;=&amp;nbsp;&amp;quot;connect/logout&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;Action&amp;nbsp;to&amp;nbsp;Configure&amp;nbsp;DbContextOptions
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;Action&amp;lt;DbContextOptionsBuilder&amp;gt;?&amp;nbsp;ActionDbContextOptions&amp;nbsp;{&amp;nbsp;get;&amp;nbsp;set;&amp;nbsp;}
}

///&amp;nbsp;&amp;lt;summary&amp;gt;
///&amp;nbsp;
///&amp;nbsp;&amp;lt;/summary&amp;gt;
public&amp;nbsp;class&amp;nbsp;OpenIddictDbContext&amp;nbsp;:&amp;nbsp;IdentityDbContext
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;options&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;OpenIddictDbContext(DbContextOptions&amp;lt;OpenIddictDbContext&amp;gt;&amp;nbsp;options)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;base(options)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;builder&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;protected&amp;nbsp;override&amp;nbsp;void&amp;nbsp;OnModelCreating(ModelBuilder&amp;nbsp;builder)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base.OnModelCreating(builder);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

///&amp;nbsp;&amp;lt;summary&amp;gt;
///&amp;nbsp;Interface&amp;nbsp;IRegisterable&amp;nbsp;
///&amp;nbsp;&amp;lt;/summary&amp;gt;
public&amp;nbsp;interface&amp;nbsp;IOIDCRegisterable
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;Register&amp;nbsp;OIDC
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;services&amp;quot;&amp;gt;Service&amp;nbsp;Collection&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void&amp;nbsp;Register(IServiceCollection&amp;nbsp;services);
}

///&amp;nbsp;&amp;lt;summary&amp;gt;
///&amp;nbsp;OpenIddict&amp;nbsp;Register
///&amp;nbsp;&amp;lt;/summary&amp;gt;
public&amp;nbsp;class&amp;nbsp;OpenIddictRegister:&amp;nbsp;Singleton&amp;lt;OpenIddictRegister&amp;gt;,&amp;nbsp;IOIDCRegisterable
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;Register&amp;nbsp;OpenIddict
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;services&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;exception&amp;nbsp;cref=&amp;quot;InvalidOperationException&amp;quot;&amp;gt;&amp;lt;/exception&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;void&amp;nbsp;Register(IServiceCollection&amp;nbsp;services)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OIDCOptions&amp;nbsp;oidcOptions;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IStringLocalizer&amp;lt;Shared&amp;gt;&amp;nbsp;SL;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;using&amp;nbsp;(var&amp;nbsp;serviceProvider&amp;nbsp;=&amp;nbsp;services.BuildServiceProvider())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oidcOptions&amp;nbsp;=&amp;nbsp;serviceProvider.GetRequiredService&amp;lt;IOptions&amp;lt;OIDCOptions&amp;gt;&amp;gt;().Value;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SL&amp;nbsp;=&amp;nbsp;serviceProvider.GetRequiredService&amp;lt;IStringLocalizer&amp;lt;Shared&amp;gt;&amp;gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;services.AddDbContext&amp;lt;OpenIddictDbContext&amp;gt;(options&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(null&amp;nbsp;!=&amp;nbsp;oidcOptions.ActionDbContextOptions)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oidcOptions.ActionDbContextOptions(options);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch&amp;nbsp;(oidcOptions.DatabaseType)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;&amp;quot;SqlServer&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Configure&amp;nbsp;Entity&amp;nbsp;Framework&amp;nbsp;Core&amp;nbsp;to&amp;nbsp;use&amp;nbsp;Microsoft&amp;nbsp;SQL&amp;nbsp;Server.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.UseSqlServer(oidcOptions.ConnectionString);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;&amp;quot;MySQL&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Configure&amp;nbsp;Entity&amp;nbsp;Framework&amp;nbsp;Core&amp;nbsp;to&amp;nbsp;use&amp;nbsp;MySQL.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.UseMySQL(oidcOptions.ConnectionString);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;&amp;quot;Sqlite&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Configure&amp;nbsp;Entity&amp;nbsp;Framework&amp;nbsp;Core&amp;nbsp;to&amp;nbsp;use&amp;nbsp;SQLite.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.UseSqlite(oidcOptions.ConnectionString);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;InvalidOperationException(SL[nameof(Shared.UnsupportedDatabaseTypeError),&amp;nbsp;oidcOptions.DatabaseType]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Register&amp;nbsp;the&amp;nbsp;entity&amp;nbsp;sets&amp;nbsp;needed&amp;nbsp;by&amp;nbsp;OpenIddict.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Note:&amp;nbsp;use&amp;nbsp;the&amp;nbsp;generic&amp;nbsp;overload&amp;nbsp;if&amp;nbsp;you&amp;nbsp;need&amp;nbsp;to&amp;nbsp;replace&amp;nbsp;the&amp;nbsp;default&amp;nbsp;OpenIddict&amp;nbsp;entities.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.UseOpenIddict();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;services.AddOpenIddict()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Register&amp;nbsp;the&amp;nbsp;OpenIddict&amp;nbsp;core&amp;nbsp;components.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.AddCore(options&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Configure&amp;nbsp;OpenIddict&amp;nbsp;to&amp;nbsp;use&amp;nbsp;the&amp;nbsp;Entity&amp;nbsp;Framework&amp;nbsp;Core&amp;nbsp;stores&amp;nbsp;and&amp;nbsp;models.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Note:&amp;nbsp;call&amp;nbsp;ReplaceDefaultEntities()&amp;nbsp;to&amp;nbsp;replace&amp;nbsp;the&amp;nbsp;default&amp;nbsp;entities.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.UseEntityFrameworkCore()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.UseDbContext&amp;lt;OpenIddictDbContext&amp;gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Register&amp;nbsp;the&amp;nbsp;OpenIddict&amp;nbsp;server&amp;nbsp;components.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.AddServer(options&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Enable&amp;nbsp;the&amp;nbsp;token&amp;nbsp;endpoint.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.SetTokenEndpointUris(oidcOptions.TokenEndpointUris);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.SetAuthorizationEndpointUris(oidcOptions.AuthorizationEndpointUris);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.SetUserInfoEndpointUris(oidcOptions.UserInfoEndpointUris);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.SetEndSessionEndpointUris(oidcOptions.EndSessionEndpointUri);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Register&amp;nbsp;the&amp;nbsp;signing&amp;nbsp;and&amp;nbsp;encryption&amp;nbsp;credentials.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.AddDevelopmentEncryptionCertificate()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.AddDevelopmentSigningCertificate();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Enable&amp;nbsp;the&amp;nbsp;client&amp;nbsp;credentials&amp;nbsp;flow.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.AllowClientCredentialsFlow();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.AllowAuthorizationCodeFlow();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.AllowRefreshTokenFlow();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Register&amp;nbsp;the&amp;nbsp;ASP.NET&amp;nbsp;Core&amp;nbsp;host&amp;nbsp;and&amp;nbsp;configure&amp;nbsp;the&amp;nbsp;ASP.NET&amp;nbsp;Core&amp;nbsp;options.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.UseAspNetCore()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.EnableTokenEndpointPassthrough()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.EnableAuthorizationEndpointPassthrough()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.EnableUserInfoEndpointPassthrough()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.EnableEndSessionEndpointPassthrough()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.DisableTransportSecurityRequirement();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Register&amp;nbsp;the&amp;nbsp;OpenIddict&amp;nbsp;validation&amp;nbsp;components.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.AddValidation(options&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Import&amp;nbsp;the&amp;nbsp;configuration&amp;nbsp;from&amp;nbsp;the&amp;nbsp;local&amp;nbsp;OpenIddict&amp;nbsp;server&amp;nbsp;instance.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.UseLocalServer();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Register&amp;nbsp;the&amp;nbsp;ASP.NET&amp;nbsp;Core&amp;nbsp;host.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.UseAspNetCore();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;services.AddDefaultIdentity&amp;lt;IdentityUser&amp;gt;(options&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.SignIn.RequireConfirmedAccount&amp;nbsp;=&amp;nbsp;true;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.SignIn.RequireConfirmedEmail&amp;nbsp;=&amp;nbsp;true;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.User.RequireUniqueEmail&amp;nbsp;=&amp;nbsp;true;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.Password.RequiredUniqueChars&amp;nbsp;=&amp;nbsp;6;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.Password.RequiredLength&amp;nbsp;=&amp;nbsp;8;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.AddEntityFrameworkStores&amp;lt;OpenIddictDbContext&amp;gt;();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;services.AddScoped&amp;lt;IOIDCExecutable,&amp;nbsp;OpenIddictExecutor&amp;gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

///&amp;nbsp;&amp;lt;summary&amp;gt;
///&amp;nbsp;
///&amp;nbsp;&amp;lt;/summary&amp;gt;
public&amp;nbsp;static&amp;nbsp;class&amp;nbsp;OpenIddictRegisterHelper
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;services&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;optionsBuidlerAction&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;static&amp;nbsp;void&amp;nbsp;AddOIDC(this&amp;nbsp;IServiceCollection&amp;nbsp;services,&amp;nbsp;Action&amp;lt;OIDCOptions&amp;gt;&amp;nbsp;optionsAction)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;services.Configure(optionsAction);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OpenIddictRegister.Instance.Register(services);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

///&amp;nbsp;&amp;lt;summary&amp;gt;
///&amp;nbsp;Interface&amp;nbsp;IOIDCExecutable&amp;nbsp;
///&amp;nbsp;&amp;lt;/summary&amp;gt;
public&amp;nbsp;interface&amp;nbsp;IOIDCExecutable
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;baseController&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;Authorize(Controller&amp;nbsp;baseController);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;baseController&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;GetUserInfo(Controller&amp;nbsp;baseController);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;baseController&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;Logout(Controller&amp;nbsp;baseController);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;baseController&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;GetToken(Controller&amp;nbsp;baseController);
}

///&amp;nbsp;&amp;lt;summary&amp;gt;
///&amp;nbsp;OpenIddict&amp;nbsp;Executor
///&amp;nbsp;&amp;lt;/summary&amp;gt;
public&amp;nbsp;class&amp;nbsp;OpenIddictExecutor&amp;nbsp;:&amp;nbsp;IOIDCExecutable
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&amp;nbsp;readonly&amp;nbsp;IOpenIddictApplicationManager&amp;nbsp;_applicationManager;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&amp;nbsp;readonly&amp;nbsp;UserManager&amp;lt;IdentityUser&amp;gt;&amp;nbsp;_userManager;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&amp;nbsp;readonly&amp;nbsp;SignInManager&amp;lt;IdentityUser&amp;gt;&amp;nbsp;_signInManager;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;applicationManager&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;userManager&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;signInManager&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;OpenIddictExecutor(IOpenIddictApplicationManager&amp;nbsp;applicationManager,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UserManager&amp;lt;IdentityUser&amp;gt;&amp;nbsp;userManager,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SignInManager&amp;lt;IdentityUser&amp;gt;&amp;nbsp;signInManager)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_applicationManager&amp;nbsp;=&amp;nbsp;applicationManager;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_userManager&amp;nbsp;=&amp;nbsp;userManager;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_signInManager&amp;nbsp;=&amp;nbsp;signInManager;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;baseController&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;exception&amp;nbsp;cref=&amp;quot;NotImplementedException&amp;quot;&amp;gt;&amp;lt;/exception&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;async&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;Authorize(Controller&amp;nbsp;baseController)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;request&amp;nbsp;=&amp;nbsp;baseController.HttpContext.GetOpenIddictServerRequest();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!request?.IsAuthorizationCodeGrantType()&amp;nbsp;??&amp;nbsp;false)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;NotImplementedException(&amp;quot;The&amp;nbsp;specified&amp;nbsp;grant&amp;nbsp;is&amp;nbsp;not&amp;nbsp;implemented.&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;authResult&amp;nbsp;=&amp;nbsp;await&amp;nbsp;baseController.HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!authResult.Succeeded)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;baseController.Challenge(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;authenticationSchemes:&amp;nbsp;IdentityConstants.ApplicationScheme,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;properties:&amp;nbsp;new&amp;nbsp;AuthenticationProperties
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RedirectUri&amp;nbsp;=&amp;nbsp;baseController.Request.PathBase&amp;nbsp;+&amp;nbsp;baseController.Request.Path&amp;nbsp;+&amp;nbsp;QueryString.Create(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;baseController.Request.HasFormContentType&amp;nbsp;?&amp;nbsp;baseController.Request.Form.ToList()&amp;nbsp;:&amp;nbsp;baseController.Request.Query.ToList())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;principal&amp;nbsp;=&amp;nbsp;new&amp;nbsp;ClaimsPrincipal(authResult.Principal);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;principal.SetScopes(request?.GetScopes());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;principal.SetClaim(Claims.Subject,&amp;nbsp;principal.FindFirstValue(ClaimTypes.NameIdentifier));

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;baseController.SignIn(principal,&amp;nbsp;OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;baseController&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;async&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;GetUserInfo(Controller&amp;nbsp;baseController)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;user&amp;nbsp;=&amp;nbsp;await&amp;nbsp;_userManager.FindByIdAsync(baseController.User?.GetClaim(Claims.Subject)&amp;nbsp;??&amp;nbsp;&amp;quot;&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(user&amp;nbsp;is&amp;nbsp;null)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;baseController.Challenge(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;authenticationSchemes:&amp;nbsp;OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;properties:&amp;nbsp;new&amp;nbsp;AuthenticationProperties(new&amp;nbsp;Dictionary&amp;lt;string,&amp;nbsp;string?&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[OpenIddictServerAspNetCoreConstants.Properties.Error]&amp;nbsp;=&amp;nbsp;Errors.InvalidToken,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription]&amp;nbsp;=
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;The&amp;nbsp;specified&amp;nbsp;access&amp;nbsp;token&amp;nbsp;is&amp;nbsp;bound&amp;nbsp;to&amp;nbsp;an&amp;nbsp;account&amp;nbsp;that&amp;nbsp;no&amp;nbsp;longer&amp;nbsp;exists.&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;claims&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Dictionary&amp;lt;string,&amp;nbsp;object&amp;gt;(StringComparer.Ordinal)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Note:&amp;nbsp;the&amp;nbsp;&amp;quot;sub&amp;quot;&amp;nbsp;claim&amp;nbsp;is&amp;nbsp;a&amp;nbsp;mandatory&amp;nbsp;claim&amp;nbsp;and&amp;nbsp;must&amp;nbsp;be&amp;nbsp;included&amp;nbsp;in&amp;nbsp;the&amp;nbsp;JSON&amp;nbsp;response.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Claims.Subject]&amp;nbsp;=&amp;nbsp;await&amp;nbsp;_userManager.GetUserIdAsync(user)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(baseController.User?.HasScope(Scopes.Email)&amp;nbsp;??&amp;nbsp;false)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;claims[Claims.Email]&amp;nbsp;=&amp;nbsp;await&amp;nbsp;_userManager.GetEmailAsync(user)&amp;nbsp;??&amp;nbsp;&amp;quot;&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;claims[Claims.EmailVerified]&amp;nbsp;=&amp;nbsp;await&amp;nbsp;_userManager.IsEmailConfirmedAsync(user);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(baseController.User?.HasScope(Scopes.Phone)&amp;nbsp;??&amp;nbsp;false)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;claims[Claims.PhoneNumber]&amp;nbsp;=&amp;nbsp;await&amp;nbsp;_userManager.GetPhoneNumberAsync(user)&amp;nbsp;??&amp;nbsp;&amp;quot;&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;claims[Claims.PhoneNumberVerified]&amp;nbsp;=&amp;nbsp;await&amp;nbsp;_userManager.IsPhoneNumberConfirmedAsync(user);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(baseController.User?.HasScope(Scopes.Roles)&amp;nbsp;??&amp;nbsp;false)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;claims[Claims.Role]&amp;nbsp;=&amp;nbsp;await&amp;nbsp;_userManager.GetRolesAsync(user);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Note:&amp;nbsp;the&amp;nbsp;complete&amp;nbsp;list&amp;nbsp;of&amp;nbsp;standard&amp;nbsp;claims&amp;nbsp;supported&amp;nbsp;by&amp;nbsp;the&amp;nbsp;OpenID&amp;nbsp;Connect&amp;nbsp;specification
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;can&amp;nbsp;be&amp;nbsp;found&amp;nbsp;here:&amp;nbsp;http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;baseController.Ok(claims);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;baseController&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;async&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;Logout(Controller&amp;nbsp;baseController)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Ask&amp;nbsp;ASP.NET&amp;nbsp;Core&amp;nbsp;Identity&amp;nbsp;to&amp;nbsp;delete&amp;nbsp;the&amp;nbsp;local&amp;nbsp;and&amp;nbsp;external&amp;nbsp;cookies&amp;nbsp;created
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;when&amp;nbsp;the&amp;nbsp;user&amp;nbsp;agent&amp;nbsp;is&amp;nbsp;redirected&amp;nbsp;from&amp;nbsp;the&amp;nbsp;external&amp;nbsp;identity&amp;nbsp;provider
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;after&amp;nbsp;a&amp;nbsp;successful&amp;nbsp;authentication&amp;nbsp;flow&amp;nbsp;(e.g&amp;nbsp;Google&amp;nbsp;or&amp;nbsp;Facebook).
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;await&amp;nbsp;_signInManager.SignOutAsync();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Returning&amp;nbsp;a&amp;nbsp;SignOutResult&amp;nbsp;will&amp;nbsp;ask&amp;nbsp;OpenIddict&amp;nbsp;to&amp;nbsp;redirect&amp;nbsp;the&amp;nbsp;user&amp;nbsp;agent
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;to&amp;nbsp;the&amp;nbsp;post_logout_redirect_uri&amp;nbsp;specified&amp;nbsp;by&amp;nbsp;the&amp;nbsp;client&amp;nbsp;application&amp;nbsp;or&amp;nbsp;to
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;the&amp;nbsp;RedirectUri&amp;nbsp;specified&amp;nbsp;in&amp;nbsp;the&amp;nbsp;authentication&amp;nbsp;properties&amp;nbsp;if&amp;nbsp;none&amp;nbsp;was&amp;nbsp;set.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;baseController.SignOut(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;authenticationSchemes:&amp;nbsp;OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;properties:&amp;nbsp;new&amp;nbsp;AuthenticationProperties
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RedirectUri&amp;nbsp;=&amp;nbsp;&amp;quot;/&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;baseController&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;exception&amp;nbsp;cref=&amp;quot;InvalidOperationException&amp;quot;&amp;gt;&amp;lt;/exception&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;exception&amp;nbsp;cref=&amp;quot;NotImplementedException&amp;quot;&amp;gt;&amp;lt;/exception&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;async&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;GetToken(Controller&amp;nbsp;baseController)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;request&amp;nbsp;=&amp;nbsp;baseController.HttpContext.GetOpenIddictServerRequest()&amp;nbsp;??
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;InvalidOperationException(&amp;quot;The&amp;nbsp;OpenID&amp;nbsp;Connect&amp;nbsp;request&amp;nbsp;cannot&amp;nbsp;be&amp;nbsp;retrieved.&amp;quot;);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(request.IsClientCredentialsGrantType())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Note:&amp;nbsp;the&amp;nbsp;client&amp;nbsp;credentials&amp;nbsp;are&amp;nbsp;automatically&amp;nbsp;validated&amp;nbsp;by&amp;nbsp;OpenIddict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;if&amp;nbsp;client_id&amp;nbsp;or&amp;nbsp;client_secret&amp;nbsp;are&amp;nbsp;invalid,&amp;nbsp;this&amp;nbsp;action&amp;nbsp;won&amp;#39;t&amp;nbsp;be&amp;nbsp;invoked.

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;application&amp;nbsp;=&amp;nbsp;await&amp;nbsp;_applicationManager.FindByClientIdAsync(request.ClientId&amp;nbsp;??&amp;nbsp;&amp;quot;&amp;quot;)&amp;nbsp;??
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;InvalidOperationException(&amp;quot;The&amp;nbsp;application&amp;nbsp;cannot&amp;nbsp;be&amp;nbsp;found.&amp;quot;);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Create&amp;nbsp;a&amp;nbsp;new&amp;nbsp;ClaimsIdentity&amp;nbsp;containing&amp;nbsp;the&amp;nbsp;claims&amp;nbsp;that
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;will&amp;nbsp;be&amp;nbsp;used&amp;nbsp;to&amp;nbsp;create&amp;nbsp;an&amp;nbsp;id_token,&amp;nbsp;a&amp;nbsp;token&amp;nbsp;or&amp;nbsp;a&amp;nbsp;code.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;identity&amp;nbsp;=&amp;nbsp;new&amp;nbsp;ClaimsIdentity(TokenValidationParameters.DefaultAuthenticationType,&amp;nbsp;Claims.Name,&amp;nbsp;Claims.Role);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Use&amp;nbsp;the&amp;nbsp;client_id&amp;nbsp;as&amp;nbsp;the&amp;nbsp;subject&amp;nbsp;identifier.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;identity.SetClaim(Claims.Subject,&amp;nbsp;await&amp;nbsp;_applicationManager.GetClientIdAsync(application));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;identity.SetClaim(Claims.Name,&amp;nbsp;await&amp;nbsp;_applicationManager.GetDisplayNameAsync(application));

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;identity.SetDestinations(static&amp;nbsp;claim&amp;nbsp;=&amp;gt;&amp;nbsp;claim.Type&amp;nbsp;switch
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Allow&amp;nbsp;the&amp;nbsp;&amp;quot;name&amp;quot;&amp;nbsp;claim&amp;nbsp;to&amp;nbsp;be&amp;nbsp;stored&amp;nbsp;in&amp;nbsp;both&amp;nbsp;the&amp;nbsp;access&amp;nbsp;and&amp;nbsp;identity&amp;nbsp;tokens
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;when&amp;nbsp;the&amp;nbsp;&amp;quot;profile&amp;quot;&amp;nbsp;scope&amp;nbsp;was&amp;nbsp;granted&amp;nbsp;(by&amp;nbsp;calling&amp;nbsp;principal.SetScopes(...)).
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Claims.Name&amp;nbsp;when&amp;nbsp;claim.Subject?.HasScope(Scopes.Profile)&amp;nbsp;??&amp;nbsp;false
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;=&amp;gt;&amp;nbsp;[Destinations.AccessToken,&amp;nbsp;Destinations.IdentityToken],

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Otherwise,&amp;nbsp;only&amp;nbsp;store&amp;nbsp;the&amp;nbsp;claim&amp;nbsp;in&amp;nbsp;the&amp;nbsp;access&amp;nbsp;tokens.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_&amp;nbsp;=&amp;gt;&amp;nbsp;[Destinations.AccessToken]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;baseController.SignIn(new&amp;nbsp;ClaimsPrincipal(identity),&amp;nbsp;OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(request.IsAuthorizationCodeGrantType()&amp;nbsp;||&amp;nbsp;request.IsRefreshTokenGrantType())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Retrieve&amp;nbsp;the&amp;nbsp;claims&amp;nbsp;principal&amp;nbsp;stored&amp;nbsp;in&amp;nbsp;the&amp;nbsp;authorization&amp;nbsp;code/refresh&amp;nbsp;token.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;result&amp;nbsp;=&amp;nbsp;await&amp;nbsp;baseController.HttpContext.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Retrieve&amp;nbsp;the&amp;nbsp;user&amp;nbsp;profile&amp;nbsp;corresponding&amp;nbsp;to&amp;nbsp;the&amp;nbsp;authorization&amp;nbsp;code/refresh&amp;nbsp;token.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;user&amp;nbsp;=&amp;nbsp;await&amp;nbsp;_userManager.FindByIdAsync(result.Principal?.GetClaim(Claims.Subject)&amp;nbsp;??&amp;nbsp;&amp;quot;&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(user&amp;nbsp;is&amp;nbsp;null)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;baseController.Forbid(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;authenticationSchemes:&amp;nbsp;OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;properties:&amp;nbsp;new&amp;nbsp;AuthenticationProperties(new&amp;nbsp;Dictionary&amp;lt;string,&amp;nbsp;string?&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[OpenIddictServerAspNetCoreConstants.Properties.Error]&amp;nbsp;=&amp;nbsp;Errors.InvalidGrant,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription]&amp;nbsp;=&amp;nbsp;&amp;quot;The&amp;nbsp;token&amp;nbsp;is&amp;nbsp;no&amp;nbsp;longer&amp;nbsp;valid.&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Ensure&amp;nbsp;the&amp;nbsp;user&amp;nbsp;is&amp;nbsp;still&amp;nbsp;allowed&amp;nbsp;to&amp;nbsp;sign&amp;nbsp;in.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!await&amp;nbsp;_signInManager.CanSignInAsync(user))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;baseController.Forbid(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;authenticationSchemes:&amp;nbsp;OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;properties:&amp;nbsp;new&amp;nbsp;AuthenticationProperties(new&amp;nbsp;Dictionary&amp;lt;string,&amp;nbsp;string?&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[OpenIddictServerAspNetCoreConstants.Properties.Error]&amp;nbsp;=&amp;nbsp;Errors.InvalidGrant,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription]&amp;nbsp;=&amp;nbsp;&amp;quot;The&amp;nbsp;user&amp;nbsp;is&amp;nbsp;no&amp;nbsp;longer&amp;nbsp;allowed&amp;nbsp;to&amp;nbsp;sign&amp;nbsp;in.&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;identity&amp;nbsp;=&amp;nbsp;new&amp;nbsp;ClaimsIdentity(result.Principal?.Claims,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;authenticationType:&amp;nbsp;TokenValidationParameters.DefaultAuthenticationType,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nameType:&amp;nbsp;Claims.Name,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;roleType:&amp;nbsp;Claims.Role);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Override&amp;nbsp;the&amp;nbsp;user&amp;nbsp;claims&amp;nbsp;present&amp;nbsp;in&amp;nbsp;the&amp;nbsp;principal&amp;nbsp;in&amp;nbsp;case&amp;nbsp;they
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;changed&amp;nbsp;since&amp;nbsp;the&amp;nbsp;authorization&amp;nbsp;code/refresh&amp;nbsp;token&amp;nbsp;was&amp;nbsp;issued.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;identity.SetClaim(Claims.Subject,&amp;nbsp;await&amp;nbsp;_userManager.GetUserIdAsync(user))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.SetClaim(Claims.Email,&amp;nbsp;await&amp;nbsp;_userManager.GetEmailAsync(user))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.SetClaim(Claims.Name,&amp;nbsp;await&amp;nbsp;_userManager.GetUserNameAsync(user))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.SetClaim(Claims.PreferredUsername,&amp;nbsp;await&amp;nbsp;_userManager.GetUserNameAsync(user))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.SetClaims(Claims.Role,&amp;nbsp;[..&amp;nbsp;(await&amp;nbsp;_userManager.GetRolesAsync(user))]);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;identity.SetDestinations(GetDestinations);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Returning&amp;nbsp;a&amp;nbsp;SignInResult&amp;nbsp;will&amp;nbsp;ask&amp;nbsp;OpenIddict&amp;nbsp;to&amp;nbsp;issue&amp;nbsp;the&amp;nbsp;appropriate&amp;nbsp;access/identity&amp;nbsp;tokens.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;baseController.SignIn(new&amp;nbsp;ClaimsPrincipal(identity),&amp;nbsp;OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;NotImplementedException(&amp;quot;The&amp;nbsp;specified&amp;nbsp;grant&amp;nbsp;is&amp;nbsp;not&amp;nbsp;implemented.&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;claim&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;string&amp;gt;&amp;nbsp;GetDestinations(Claim&amp;nbsp;claim)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Note:&amp;nbsp;by&amp;nbsp;default,&amp;nbsp;claims&amp;nbsp;are&amp;nbsp;NOT&amp;nbsp;automatically&amp;nbsp;included&amp;nbsp;in&amp;nbsp;the&amp;nbsp;access&amp;nbsp;and&amp;nbsp;identity&amp;nbsp;tokens.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;To&amp;nbsp;allow&amp;nbsp;OpenIddict&amp;nbsp;to&amp;nbsp;serialize&amp;nbsp;them,&amp;nbsp;you&amp;nbsp;must&amp;nbsp;attach&amp;nbsp;them&amp;nbsp;a&amp;nbsp;destination,&amp;nbsp;that&amp;nbsp;specifies
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;whether&amp;nbsp;they&amp;nbsp;should&amp;nbsp;be&amp;nbsp;included&amp;nbsp;in&amp;nbsp;access&amp;nbsp;tokens,&amp;nbsp;in&amp;nbsp;identity&amp;nbsp;tokens&amp;nbsp;or&amp;nbsp;in&amp;nbsp;both.

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch&amp;nbsp;(claim.Type)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;Claims.Name&amp;nbsp;or&amp;nbsp;Claims.PreferredUsername:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;return&amp;nbsp;Destinations.AccessToken;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(claim.Subject?.HasScope(Scopes.Profile)&amp;nbsp;??&amp;nbsp;false)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;return&amp;nbsp;Destinations.IdentityToken;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;break;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;Claims.Email:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;return&amp;nbsp;Destinations.AccessToken;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(claim.Subject?.HasScope(Scopes.Email)&amp;nbsp;??&amp;nbsp;false)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;return&amp;nbsp;Destinations.IdentityToken;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;break;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;Claims.Role:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;return&amp;nbsp;Destinations.AccessToken;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(claim.Subject?.HasScope(Scopes.Roles)&amp;nbsp;??&amp;nbsp;false)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;return&amp;nbsp;Destinations.IdentityToken;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;break;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Never&amp;nbsp;include&amp;nbsp;the&amp;nbsp;security&amp;nbsp;stamp&amp;nbsp;in&amp;nbsp;the&amp;nbsp;access&amp;nbsp;and&amp;nbsp;identity&amp;nbsp;tokens,&amp;nbsp;as&amp;nbsp;it&amp;#39;s&amp;nbsp;a&amp;nbsp;secret&amp;nbsp;value.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;&amp;quot;AspNet.Identity.SecurityStamp&amp;quot;:&amp;nbsp;yield&amp;nbsp;break;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;return&amp;nbsp;Destinations.AccessToken;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;break;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;IOIDCRegisterable是注册OpenIddict的契约接口、IOIDCExecutable是OpenIddict各种授权流程具体实现的契约接口，使用本机服务端验证AccessToken。&lt;/p&gt;&lt;p&gt;3、在Program.cs如下设置：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-csharp&quot;&gt;using&amp;nbsp;Microsoft.AspNetCore.Localization;
using&amp;nbsp;RockstackAdmin.Infra.Common.Resources;
using&amp;nbsp;RockstackAdmin.Infra.OIDC.OpenIddict;
using&amp;nbsp;System.Globalization;

var&amp;nbsp;builder&amp;nbsp;=&amp;nbsp;WebApplication.CreateBuilder(args);
var&amp;nbsp;services&amp;nbsp;=&amp;nbsp;builder.Services;
var&amp;nbsp;configuration&amp;nbsp;=&amp;nbsp;builder.Configuration;

services.AddLocalization();
services.AddRazorPages();
services.AddControllersWithViews(options&amp;nbsp;=&amp;gt;
{

})
.AddViewLocalization()
.AddDataAnnotationsLocalization(options&amp;nbsp;=&amp;gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.DataAnnotationLocalizerProvider&amp;nbsp;=&amp;nbsp;(type,&amp;nbsp;factory)&amp;nbsp;=&amp;gt;&amp;nbsp;factory.Create(typeof(Shared));
});

const&amp;nbsp;string&amp;nbsp;defaultCulture&amp;nbsp;=&amp;nbsp;&amp;quot;en&amp;quot;;
var&amp;nbsp;supportedCultures&amp;nbsp;=&amp;nbsp;new[]
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new&amp;nbsp;CultureInfo(defaultCulture),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new&amp;nbsp;CultureInfo(&amp;quot;ko&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new&amp;nbsp;CultureInfo(&amp;quot;zh-CN&amp;quot;),
};
services.Configure&amp;lt;RequestLocalizationOptions&amp;gt;(options&amp;nbsp;=&amp;gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.DefaultRequestCulture&amp;nbsp;=&amp;nbsp;new&amp;nbsp;RequestCulture(defaultCulture);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.SupportedCultures&amp;nbsp;=&amp;nbsp;supportedCultures;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.SupportedUICultures&amp;nbsp;=&amp;nbsp;supportedCultures;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.ApplyCurrentCultureToResponseHeaders&amp;nbsp;=&amp;nbsp;true;
});

services.AddOIDC(options&amp;nbsp;=&amp;gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.DatabaseType&amp;nbsp;=&amp;nbsp;configuration.GetValueByPath(&amp;quot;OIDC.DatabaseType&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.ConnectionString&amp;nbsp;=&amp;nbsp;configuration.GetValueByPath(&amp;quot;OIDC.ConnectionString&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.AuthorizationEndpointUris&amp;nbsp;=&amp;nbsp;configuration.GetValueByPath(&amp;quot;OIDC.AuthorizationEndpointUris&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.EndSessionEndpointUri&amp;nbsp;=&amp;nbsp;configuration.GetValueByPath(&amp;quot;OIDC.EndSessionEndpointUri&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.TokenEndpointUris&amp;nbsp;=&amp;nbsp;configuration.GetValueByPath(&amp;quot;OIDC.TokenEndpointUris&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.UserInfoEndpointUris&amp;nbsp;=&amp;nbsp;configuration.GetValueByPath(&amp;quot;OIDC.UserInfoEndpointUris&amp;quot;);
});

var&amp;nbsp;app&amp;nbsp;=&amp;nbsp;builder.Build();

app.UseRequestLocalization();

app.UseDeveloperExceptionPage();

app.UseForwardedHeaders();

app.UseRouting();
app.UseCors();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;&amp;quot;default&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pattern:&amp;nbsp;&amp;quot;{controller=Home}/{action=Index}/{id?}&amp;quot;);
app.MapRazorPages();

app.Run();&lt;/pre&gt;&lt;p&gt;4、appsettings.json配置：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;OIDC&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;DatabaseType&amp;quot;:&amp;nbsp;&amp;quot;Sqlite&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;ConnectionString&amp;quot;:&amp;nbsp;&amp;quot;Data&amp;nbsp;Source=oidc.sqlite;Password=;Mode=ReadWriteCreate;Cache=Shared;Pooling=True;Default&amp;nbsp;Timeout=5;&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;TokenEndpointUris&amp;quot;:&amp;nbsp;&amp;quot;connect/token&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;AuthorizationEndpointUris&amp;quot;:&amp;nbsp;&amp;quot;connect/authorize&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;UserInfoEndpointUris&amp;quot;:&amp;nbsp;&amp;quot;connect/userinfo&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;EndSessionEndpointUri&amp;quot;:&amp;nbsp;&amp;quot;connect/logout&amp;quot;
&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;quot;Logging&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;LogLevel&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;Default&amp;quot;:&amp;nbsp;&amp;quot;Information&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;Microsoft.AspNetCore&amp;quot;:&amp;nbsp;&amp;quot;Warning&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;quot;AllowedHosts&amp;quot;:&amp;nbsp;&amp;quot;*&amp;quot;
}&lt;/pre&gt;&lt;p&gt;5、控制器：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-csharp&quot;&gt;///&amp;nbsp;&amp;lt;summary&amp;gt;
///&amp;nbsp;
///&amp;nbsp;&amp;lt;/summary&amp;gt;
public&amp;nbsp;class&amp;nbsp;OIDCController&amp;nbsp;:&amp;nbsp;Controller
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&amp;nbsp;readonly&amp;nbsp;IOIDCExecutable&amp;nbsp;_oidcExecutable;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;param&amp;nbsp;name=&amp;quot;oidcExecutable&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;OIDCController(IOIDCExecutable&amp;nbsp;oidcExecutable)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_oidcExecutable&amp;nbsp;=&amp;nbsp;oidcExecutable;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[HttpGet(&amp;quot;~/connect/authorize&amp;quot;),&amp;nbsp;HttpPost(&amp;quot;~/connect/authorize&amp;quot;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;async&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;Authorize()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;await&amp;nbsp;_oidcExecutable.Authorize(this);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Authorize(AuthenticationSchemes&amp;nbsp;=&amp;nbsp;OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[HttpPost(&amp;quot;~/connect/userinfo&amp;quot;),&amp;nbsp;Consumes(&amp;quot;application/json&amp;quot;),&amp;nbsp;Produces(&amp;quot;application/json&amp;quot;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;async&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;GetUserInfo()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;await&amp;nbsp;_oidcExecutable.GetUserInfo(this);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Authorize(AuthenticationSchemes&amp;nbsp;=&amp;nbsp;OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[HttpPost(&amp;quot;~/connect/logout&amp;quot;),&amp;nbsp;Consumes(&amp;quot;application/json&amp;quot;),&amp;nbsp;Produces(&amp;quot;application/json&amp;quot;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;async&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;Logout()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;await&amp;nbsp;_oidcExecutable.Logout(this);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;/summary&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;nbsp;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[HttpPost(&amp;quot;~/connect/token&amp;quot;),&amp;nbsp;Consumes(&amp;quot;application/json&amp;quot;),&amp;nbsp;Produces(&amp;quot;application/json&amp;quot;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;async&amp;nbsp;Task&amp;lt;IActionResult&amp;gt;&amp;nbsp;GetToken()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;await&amp;nbsp;_oidcExecutable.GetToken(this);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;~/connect/authorize：Authorization Code授权流程的入口页；&lt;/p&gt;&lt;p&gt;~/connect/userinfo：获取当前用户信息接口页；&lt;/p&gt;&lt;p&gt;~/connect/logout：注销登录接口页；&lt;/p&gt;&lt;p&gt;~/connect/token：获得AccessToken的接口页。&lt;br/&gt;&lt;/p&gt;</description><pubDate>Mon, 27 Oct 2025 15:19:13 +0800</pubDate></item><item><title>OpenIddict从零开始（二）——授权流程</title><link>https://www.9icode.com/index.php/post/391.html</link><description>&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OpenIddict内置5种授权流程：&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;授权码流程（Authorization Code Flow）&lt;/p&gt;&lt;p&gt;支持PKCE，最推荐。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;隐式流程（Implicit Flow）&lt;/p&gt;&lt;p&gt;出于历史遗留原因该流程仅在OpenIddict服务端库中支持，但在OpenIddict客户端库不支持。该流程已过时。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;混合流程（Hybrid Flow）&lt;/p&gt;&lt;p&gt;介于授权码流程和隐式流程之间的一种混合流程。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;资源所有者密码凭证授权流程（Resource Owner Password Credentials Grant Flow）&lt;/p&gt;&lt;p&gt;因安全原因该流程应在其它流程都不适用时才考虑采用。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;客户端凭证授权流程（Client Credentials Grant&amp;nbsp;Flow）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;设备授权流程（Device Grant Flow）&lt;br/&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr class=&quot;firstRow&quot;&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;&lt;strong&gt;授权流程&lt;/strong&gt;&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;&lt;strong&gt;是否交互&lt;/strong&gt;&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;&lt;strong&gt;应用场景&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;Authorization Code Flow (PKCE)&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;是&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;SPA单页面应用、Web应用&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;Implicit Flow&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;是&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;SPA单页面应用&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;Hybrid Flow&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;是&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;SPA单页面应用、Web应用&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;Resource Owner Password Credentials Grant Flow&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;否&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;第一方原生应用或高度信任的内部系统&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;Client Credentials Grant&amp;nbsp;Flow&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;否&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;&lt;p&gt;服务端内部、服务端之间、定时任务、后台作业、不需要特定用户上下文的接口调用&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;Device Grant&amp;nbsp;Flow&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;是&lt;/td&gt;&lt;td width=&quot;468&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot; class=&quot;selectTdClass&quot;&gt;&lt;p&gt;不带浏览器的IoT设备等&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Mon, 27 Oct 2025 14:51:49 +0800</pubDate></item><item><title>OpenIddict从零开始（一）——概述</title><link>https://www.9icode.com/index.php/post/390.html</link><description>&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OpenIddict是一个免费、开源、多功能、可自定义、基于.NET的OAuth 2.0和OIDC（Open ID Connect）库，可以帮助实现.NET应用的OIDC服务端、客户端和令牌验证。支持.NET Framework 4.6.2+, .NET Core 2.3+ 和.NET 8+，需与Identity配合使用。&lt;strong&gt;Identity 负责“这个用户是谁”以及“他/她在我的应用里有什么身份”，&lt;strong&gt;OpenIddict 负责“这个客户端应用是否有权限代表某个用户访问特定资源”并颁发一个被广泛认可的通行证（如JWT Token）。&lt;/strong&gt;&lt;/strong&gt;主要用途包括：单点登录、第三方应用授权等。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;OIDC客户端模块可以用来和任何标准OIDC服务器交互；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;OIDC服务端模块可以用来实现自己的标准OIDC服务器；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;OIDC令牌验证模块可以用来和OIDC服务器通信以实现用户认证。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;在.NET Framework 4.6.2上，不支持&lt;code&gt;以下方法&lt;code&gt;，都将抛出&lt;code&gt;PlatformNotSupportedException&lt;/code&gt;异常：&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;AddSigningCertificate、AddSigningKey()；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;无可用开发证书时AddDevelopmentEncryptionCertificate()；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;无可用开发证书时AddDevelopmentSigningCertificate()。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;OpenIddict官网：&lt;a href=&quot;https://openiddict.com&quot; _src=&quot;https://openiddict.com&quot;&gt;https://openiddict.com&lt;/a&gt;&lt;/p&gt;&lt;p&gt;OAuth 2.0规范: &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc6749&quot; _src=&quot;https://datatracker.ietf.org/doc/html/rfc6749&quot;&gt;https://datatracker.ietf.org/doc/html/rfc6749&lt;/a&gt;&lt;/p&gt;&lt;p&gt;OpenID Connect规范：&lt;a href=&quot;https://openid.net/specs/openid-connect-core-1_0.html&quot; _src=&quot;https://openid.net/specs/openid-connect-core-1_0.html&quot;&gt;https://openid.net/specs/openid-connect-core-1_0.html&lt;/a&gt;&lt;/p&gt;</description><pubDate>Mon, 27 Oct 2025 14:16:40 +0800</pubDate></item><item><title>开放接口无版本化有哪些策略？</title><link>https://www.9icode.com/index.php/post/389.html</link><description>&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;font-size: 14px;&quot;&gt;开放接口无版本化适用于对长期稳定性和可演进性要求极高的系统。&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;1. 资源表示扩展（Resource Representation Extension）&lt;/h4&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;核心思想&lt;/strong&gt;：API的根端点（或一个发现端点）返回所有可用资源的链接，客户端通过跟随这些链接来操作。版本升级时，通过添加新字段、新链接或弃用旧字段来实现，而不改变核心URL。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;示例：&lt;/strong&gt;&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;请求 &lt;code&gt;GET /users/123&lt;/code&gt;&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;v1 返回：&lt;/p&gt;&lt;pre&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;id&amp;quot;:&amp;nbsp;123,
&amp;nbsp;&amp;nbsp;&amp;quot;name&amp;quot;:&amp;nbsp;&amp;quot;Alice&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;email&amp;quot;:&amp;nbsp;&amp;quot;alice@example.com&amp;quot;}&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;v2 返回：&lt;/p&gt;&lt;pre&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;id&amp;quot;:&amp;nbsp;123,
&amp;nbsp;&amp;nbsp;&amp;quot;name&amp;quot;:&amp;nbsp;&amp;quot;Alice&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;email&amp;quot;:&amp;nbsp;&amp;quot;alice@example.com&amp;quot;,
&amp;nbsp;&amp;nbsp;//&amp;nbsp;新增字段
&amp;nbsp;&amp;nbsp;&amp;quot;avatar_url&amp;quot;:&amp;nbsp;&amp;quot;https://...&amp;quot;,
&amp;nbsp;&amp;nbsp;//&amp;nbsp;添加超媒体控制，这是关键
&amp;nbsp;&amp;nbsp;&amp;quot;_links&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;self&amp;quot;:&amp;nbsp;{&amp;nbsp;&amp;quot;href&amp;quot;:&amp;nbsp;&amp;quot;/users/123&amp;quot;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;posts&amp;quot;:&amp;nbsp;{&amp;nbsp;&amp;quot;href&amp;quot;:&amp;nbsp;&amp;quot;/users/123/posts&amp;quot;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;}}&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;URL永久稳定，符合REST的最高理想。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;通过添加而非修改来演进API，向后兼容性好。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;实现复杂&lt;/strong&gt;：需要精心设计字段和超媒体控制（HATEOAS）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;客户端必须忽略未知字段&lt;/strong&gt;：要求客户端遵循“稳健性原则”。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;沟通成本高&lt;/strong&gt;：需要明确告知客户端哪些字段已弃用，以及何时会移除。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;2. 容忍性读取，严格性写入&lt;/h3&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;读取操作&lt;/strong&gt;：服务器总是返回最完整的资源表示，客户端应忽略不认识的字段。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;写入操作&lt;/strong&gt;：客户端总是发送它知道的所有字段，服务器应忽略不认识的字段。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;示例：&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot;md-code-block md-code-block-light&quot;&gt;&lt;div class=&quot;md-code-block-banner-wrap&quot;&gt;&lt;div class=&quot;md-code-block-banner md-code-block-banner-lite&quot;&gt;&lt;div class=&quot;_121d384&quot;&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;#&amp;nbsp;客户端（老版本）只知道name和email
PUT&amp;nbsp;/users/123&amp;nbsp;HTTP/1.1
{
&amp;nbsp;&amp;nbsp;&amp;quot;name&amp;quot;:&amp;nbsp;&amp;quot;Alice&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;email&amp;quot;:&amp;nbsp;&amp;quot;alice@example.com&amp;quot;
&amp;nbsp;&amp;nbsp;#&amp;nbsp;不知道新的avatar_url字段
}

#&amp;nbsp;服务器（新版本）保存已知字段，忽略未知字段&lt;/pre&gt;&lt;h3&gt;3. 功能开关（Feature Toggle）&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;通过功能开关控制新老逻辑，而不是通过版本号。&lt;/p&gt;&lt;div class=&quot;md-code-block md-code-block-light&quot;&gt;&lt;div class=&quot;md-code-block-banner-wrap&quot;&gt;&lt;div class=&quot;md-code-block-banner md-code-block-banner-lite&quot;&gt;&lt;div class=&quot;_121d384&quot;&gt;&lt;div class=&quot;d2a24f03&quot;&gt;&lt;span class=&quot;d813de27&quot;&gt;http&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre&gt;GET&amp;nbsp;/users/123&amp;nbsp;HTTP/1.1X-Feature-Flags:&amp;nbsp;new_avatar_system,enhanced_search&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点：&lt;/strong&gt; 细粒度控制，可以逐步发布新功能。&lt;br/&gt;&lt;strong&gt;缺点：&lt;/strong&gt; 客户端复杂度增加，需要管理功能开关状态。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3&gt;4. 智能版本推理&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;服务器通过分析请求特征自动推断合适的版本。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;GET&amp;nbsp;/users/123&amp;nbsp;HTTP/1.1
User-Agent:&amp;nbsp;CompanyApp/3.2.1
X-Device-Type:&amp;nbsp;mobile
#&amp;nbsp;服务器根据UserAgent、设备类型、访问模式等自动选择v2&amp;nbsp;AP&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点&lt;/strong&gt;: 对客户端透明，无需显式版本声明。&lt;br/&gt;&lt;strong&gt;缺点&lt;/strong&gt;: 可能产生错误推断，调试困难。&lt;br/&gt;&lt;strong&gt;适用场景&lt;/strong&gt;: 拥有固定客户端生态的系统。&lt;/p&gt;&lt;h3&gt;5. 行为检测版本选择&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;通过分析请求内容和模式来动态选择API版本。&lt;/p&gt;&lt;div class=&quot;md-code-block md-code-block-light&quot;&gt;&lt;div class=&quot;md-code-block-banner-wrap&quot;&gt;&lt;div class=&quot;md-code-block-banner md-code-block-banner-lite&quot;&gt;&lt;div class=&quot;_121d384&quot;&gt;&lt;div class=&quot;d2a24f03&quot;&gt;&lt;span class=&quot;d813de27&quot;&gt;http&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre&gt;POST&amp;nbsp;/users&amp;nbsp;HTTP/1.1
Content-Type:&amp;nbsp;application/json

{
&amp;nbsp;&amp;nbsp;&amp;quot;name&amp;quot;:&amp;nbsp;&amp;quot;Alice&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;email&amp;quot;:&amp;nbsp;&amp;quot;alice@example.com&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;preferences&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;newsletter&amp;quot;:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;two_factor_auth&amp;quot;:&amp;nbsp;true&amp;nbsp;&amp;nbsp;#&amp;nbsp;新版本才有的字段&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
#&amp;nbsp;服务器检测到新版本特有的字段，自动使用v2逻辑处理&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点&lt;/strong&gt;: 智能适配，减少版本冲突。&lt;br/&gt;&lt;strong&gt;缺点&lt;/strong&gt;: 处理逻辑复杂，性能开销大。&lt;br/&gt;&lt;strong&gt;适用场景&lt;/strong&gt;: 渐进式迁移过程中的临时方案。&lt;/p&gt;</description><pubDate>Mon, 27 Oct 2025 13:53:12 +0800</pubDate></item><item><title>开放接口版本号可以放在哪些位置？</title><link>https://www.9icode.com/index.php/post/388.html</link><description>&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;开放接口版本号的设计位置会影响到API的易用性、可维护性以及是否符合RESTful规范。可以作为版本号一部分的有：1.0.0.0格式自定义版本号、时间戳、Git提交Hash等。总的来说，接口版本号主要有以下几种常见位置，各有优劣：&lt;/p&gt;&lt;h3&gt;1. URL路径（URI Path）&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;这是最常见、最直观的方式，将版本号直接放在API的URL中。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;格式：&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;https://api.example.com/v1/users
https://api.example.com/v2/users&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;示例：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;GitHub API:&amp;nbsp;&lt;code&gt;https://api.github.com/v3/user&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;Twitter API: &lt;code&gt;https://api.twitter.com/1.1/statuses/home_timeline.json&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;极其直观&lt;/strong&gt;：用户一眼就能看出使用的是哪个版本。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;易于访问和测试&lt;/strong&gt;：直接在浏览器地址栏输入即可测试。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;部署简单&lt;/strong&gt;：可以通过路径将不同版本的请求路由到不同的服务器或服务上（例如，&lt;code&gt;/v1/&lt;/code&gt; 路由到服务A，&lt;code&gt;/v2/&lt;/code&gt; 路由到服务B）。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;不符合纯REST理念&lt;/strong&gt;：从资源的角度看，版本号不属于资源本身的一部分，URL应该始终指向同一个“逻辑”资源。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;URL污染&lt;/strong&gt;：版本号使得URL变得稍长。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;结论：&lt;/strong&gt; &lt;strong&gt;这是最推荐、最通用的做法&lt;/strong&gt;，尤其是在需要频繁迭代、版本间差异较大的公开API中。&lt;/p&gt;&lt;h3&gt;2. 查询参数（Query String）&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;将版本号作为一个参数附加在URL的查询部分。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;格式：&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;https://api.example.com/users?version=1
https://api.example.com/users?v=2&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;示例：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;不常见于主流API，但一些内部服务或早期API可能会使用。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;不改变基础URL&lt;/strong&gt;：资源的主路径保持不变。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;实现简单&lt;/strong&gt;：后端可以通过解析参数来区分版本。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;不够明显&lt;/strong&gt;：版本信息容易被忽略。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缓存复杂性&lt;/strong&gt;：某些缓存代理可能会忽略查询字符串，导致缓存键不一致。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;语义&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;较弱&lt;/strong&gt;：通常认为查询参数用于过滤、排序，而非定义API的根本契约。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;3. 自定义请求头（Custom Header）&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;使用HTTP请求头来传递版本信息。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;格式：&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;GET&amp;nbsp;/users&amp;nbsp;HTTP/1.1
Host:&amp;nbsp;api.example.com
Accept-Version:&amp;nbsp;v1&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;或者使用更标准的 &lt;code&gt;Accept&lt;/code&gt; 头变体：&lt;/p&gt;&lt;pre&gt;GET&amp;nbsp;/users&amp;nbsp;HTTP/1.1
Host:&amp;nbsp;api.example.com
Accept:&amp;nbsp;application/vnd.example.v1+json&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;示例：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;code&gt;Accept: application/vnd.github.v3+json&lt;/code&gt; (GitHub也支持这种方式，作为URL路径的补充)&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;保持URL干净&lt;/strong&gt;：URL完全不包含版本信息，纯粹指向资源。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;非常符合REST规范&lt;/strong&gt;：利用HTTP内容协商机制，语义清晰。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;灵活性强&lt;/strong&gt;：可以同时支持多个版本，由服务器根据头信息决定返回哪个表示。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;使用不便&lt;/strong&gt;：无法直接在浏览器地址栏中测试，必须借助工具（如Postman, curl）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;可发现性差&lt;/strong&gt;：开发者需要查阅文档才知道要加什么头。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缓存配置&lt;/strong&gt;：需要确保缓存机制将版本头作为缓存键的一部分。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;结论：&lt;/strong&gt; &lt;strong&gt;适用于对RESTful原则要求极高、或客户端环境可控（如内部微服务、单页应用）的场景。&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;Host:&amp;nbsp;api.example.com
Accept:&amp;nbsp;application/vnd.example.v1+json&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;示例：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;code&gt;Accept: application/vnd.github.v3+json&lt;/code&gt; (GitHub也支持这种方式，作为URL路径的补充)&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;保持URL干净&lt;/strong&gt;：URL完全不包含版本信息，纯粹指向资源。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;非常符合REST规范&lt;/strong&gt;：利用HTTP内容协商机制，语义清晰。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;灵活性强&lt;/strong&gt;：可以同时支持多个版本，由服务器根据头信息决定返回哪个表示。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;使用不便&lt;/strong&gt;：无法直接在浏览器地址栏中测试，必须借助工具（如Postman, curl）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;可发现性差&lt;/strong&gt;：开发者需要查阅文档才知道要加什么头。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缓存配置&lt;/strong&gt;：需要确保缓存机制将版本头作为缓存键的一部分。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;结论：&lt;/strong&gt; &lt;strong&gt;适用于对RESTful原则要求极高、或客户端环境可控（如内部微服务、单页应用）的场景。&lt;/strong&gt;&lt;/p&gt;&lt;h3&gt;4. 媒体类型（Media Type / Content Negotiation）&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;这是“自定义请求头”的一种更正式、更标准化的形式，利用HTTP的 &lt;code&gt;Accept&lt;/code&gt; 头进行&lt;strong&gt;内容协商&lt;/strong&gt;。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;格式：&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;GET&amp;nbsp;/users&amp;nbsp;HTTP/1.1
Host:&amp;nbsp;api.example.com
Accept:&amp;nbsp;application/vnd.myapi.v2+json&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;在这里，&lt;code&gt;vnd.myapi.v2+json&lt;/code&gt; 是一个自定义的媒体类型，表示“我请求版本2的JSON格式数据”。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;是REST的最佳实践&lt;/strong&gt;：完全利用HTTP协议自身机制。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;功能强大&lt;/strong&gt;：不仅可以协商版本，还可以协商数据格式（JSON/XML等）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;向前兼容性好&lt;/strong&gt;：可以定义默认版本，当客户端不指定 &lt;code&gt;Accept&lt;/code&gt; 头时使用。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;使用最不方便&lt;/strong&gt;：对开发者不友好，测试和调试复杂。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;可发现性最差&lt;/strong&gt;。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;结论：&lt;/strong&gt; &lt;strong&gt;通常是大型、成熟API平台（如GitHub）的进阶选择，或者是内部架构非常规范的微服务系统的选择&lt;/strong&gt;&lt;/p&gt;&lt;h3&gt;5. 域名（Host/Subdomain）&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;将版本号放在子域名或独立的域名上。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;格式：&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;https://v1.api.example.com/users
https://api.example.com/v2/users/&amp;nbsp;(这个属于路径，注意区分)&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;示例：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;code&gt;https://developer.github.com/v3/&lt;/code&gt; (文档域名，非API域名)&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;完全隔离&lt;/strong&gt;：不同版本的API可以部署在完全独立的基础设施上，互不影响。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;技术栈无关&lt;/strong&gt;：v1可以用Java，v2可以用Go，互不干扰。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;部署和运维成本高&lt;/strong&gt;：需要管理多个域名和服务器环境。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;SSL证书&lt;/strong&gt;：可能需要为每个子域名配置SSL证书。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;跨域问题&lt;/strong&gt;：如果主站在不同域名，可能会遇到CORS问题。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;结论：&lt;/strong&gt; &lt;strong&gt;适用于需要极端隔离的大型、重大版本升级，一般不用于常规的迭代。&lt;/strong&gt;&lt;/p&gt;&lt;h3&gt;6. 扩展方案与特殊思路&lt;/h3&gt;&lt;h4&gt;6.1 配置文件/契约驱动（Configuration Driven）&lt;/h4&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;版本信息不通过请求传递，而是通过外部的&lt;strong&gt;配置文件或API契约&lt;/strong&gt;来定义。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;核心思想&lt;/strong&gt;：客户端和服务器通过共享一个API契约（如OpenAPI/Swagger规范）来绑定版本。在部署或集成时，客户端库会根据指定的契约版本生成对应的代码。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;示例：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;项目中有 &lt;code&gt;openapi-v1.yaml&lt;/code&gt; 和 &lt;code&gt;openapi-v2.yaml&lt;/code&gt; 两个文件。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;客户端SDK通过 &lt;code&gt;npm install my-api-client@v1&lt;/code&gt; 来引入对应版本的客户端，这个客户端内部所有方法都已固定为v1的端点。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;类型安全&lt;/strong&gt;：客户端在编译时即可发现错误。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;强约束&lt;/strong&gt;：版本在集成阶段就已确定，避免了运行时的不一致。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;适用于SDK&lt;/strong&gt;：对于提供官方SDK的API来说非常合适。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;灵活性差&lt;/strong&gt;：难以在运行时动态切换版本。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;不适用于直接HTTP调用&lt;/strong&gt;：主要用于有SDK封装的场景。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;部署复杂&lt;/strong&gt;：需要维护和发布多套客户端库。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;结论&lt;/strong&gt;：在 &lt;strong&gt;微服务内部通信&lt;/strong&gt; 或 &lt;strong&gt;提供强类型SDK的公有云服务&lt;/strong&gt; 中比较常见。&lt;/p&gt;&lt;h4&gt;6.2 组合策略（Hybrid Approaches）&lt;/h4&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;在实际生产中，很多公司会采用组合策略来兼顾灵活性和兼容性。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;默认路径 + 头重写&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;默认&lt;/strong&gt;：使用URL路径（如 &lt;code&gt;/v1/&lt;/code&gt;）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;重写&lt;/strong&gt;：通过一个特殊的请求头（如 &lt;code&gt;X-Api-Version: 2&lt;/code&gt;）来覆盖URL中指定的版本。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;用途&lt;/strong&gt;：方便内部测试和调试，无需修改URL。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;路径为主，头部为辅&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;像GitHub API，主要使用路径 &lt;code&gt;/v3/&lt;/code&gt;，但同时完全支持通过 &lt;code&gt;Accept: application/vnd.github.v3+json&lt;/code&gt; 头来指定版本。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;用途&lt;/strong&gt;：提供最大限度的开发者友好性和灵活性。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;7. HTTP 重定向版本协商&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;客户端访问一个无版本的入口端点，服务器通过HTTP重定向到对应版本。&lt;/p&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;示例：&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;#&amp;nbsp;初始请求（无版本）
GET&amp;nbsp;/api/users/123&amp;nbsp;HTTP/1.1
Host:&amp;nbsp;example.com

#&amp;nbsp;服务器响应
HTTP/1.1&amp;nbsp;302&amp;nbsp;Found
Location:&amp;nbsp;https://api.example.com/v2/users/123&lt;/pre&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;优点：&lt;/strong&gt; 客户端无需关心版本。&lt;br/&gt;&lt;strong&gt;缺点：&lt;/strong&gt; 额外的重定向开销，对性能敏感的场景不适用。&lt;br/&gt;&lt;strong&gt;适用场景：&lt;/strong&gt; 内部服务发现，或者希望强制客户端使用最新版本的场景。&lt;/p&gt;</description><pubDate>Mon, 27 Oct 2025 13:19:56 +0800</pubDate></item><item><title>.NET如何使用SqlSugar加密读写SQLite</title><link>https://www.9icode.com/index.php/post/385.html</link><description>&lt;p&gt;1、引用SqlSugarCore和QLitePCLRaw.bundle_e_sqlcipher；&lt;/p&gt;&lt;p&gt;2、SQLite连接字符串：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-csharp&quot;&gt;Data&amp;nbsp;Source=test.sqlite;Password=pwd;&lt;/pre&gt;&lt;p&gt;3、调用SqlSugar连接SQLite：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-csharp&quot;&gt;var&amp;nbsp;sqliteDb&amp;nbsp;=&amp;nbsp;new&amp;nbsp;SqlSugarScope(new&amp;nbsp;ConnectionConfig()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ConnectionString&amp;nbsp;=&amp;nbsp;&amp;quot;Data&amp;nbsp;Source=test.sqlite;Password=pwd;&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DbType&amp;nbsp;=&amp;nbsp;DbType.Sqlite,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IsAutoCloseConnection&amp;nbsp;=&amp;nbsp;true
},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client.Aop.OnError&amp;nbsp;=&amp;nbsp;(ex)&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client.Aop.OnLogExecuting&amp;nbsp;=&amp;nbsp;(sql,&amp;nbsp;pars)&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;sqlRaw&amp;nbsp;=&amp;nbsp;UtilMethods.GetSqlString(DbType.Sqlite,&amp;nbsp;sql,&amp;nbsp;pars);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&lt;/pre&gt;&lt;p&gt;4、关于SQLite数据管理软件：推荐DB Browser for SQLite，使用DB Browser for SQLCipher打开加密SQLite；&lt;/p&gt;&lt;p&gt;5、关于加密：&lt;/p&gt;&lt;p&gt;（1）直接使用DB Browser for SQLite给SQLite数据库文件加密后，SqlSugar不能打开；&lt;/p&gt;&lt;p&gt;（2）如上代码会自动创建一个已加密的空白SQLite数据库文件，可以使用DB Browser for SQLCipher打开该文件。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Thu, 20 Feb 2025 18:43:14 +0800</pubDate></item><item><title>.NET如何使用SqlSugar读写Access</title><link>https://www.9icode.com/index.php/post/384.html</link><description>&lt;p&gt;1、引用SqlSugarCore和SqlSugar.AccessCore；&lt;/p&gt;&lt;p&gt;2、Access连接字符串：&lt;/p&gt;&lt;p&gt;2007版本之前&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-csharp&quot;&gt;Provider=Microsoft.Jet.OleDb.4.0;Data&amp;nbsp;Source=test.mdb;Persist&amp;nbsp;Security&amp;nbsp;Info=False;Password=;&lt;/pre&gt;&lt;p&gt;2007版本及之后&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-csharp&quot;&gt;Provider=Microsoft.ACE.OleDB.15.0;Data&amp;nbsp;Source=test.accdb;Persist&amp;nbsp;Security&amp;nbsp;Info=False;Password=;&lt;/pre&gt;&lt;p&gt;其中的Access驱动版本号因Access版本不同而不同，同时需安装对应的Access驱动（32位或64位）。若安装了32位驱动，则应用程序也需要生成x86版本；64位则需要生成x64版本。&lt;/p&gt;&lt;p&gt;3、调用SqlSugar连接Access：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-csharp&quot;&gt;var&amp;nbsp;accessDb&amp;nbsp;=&amp;nbsp;new&amp;nbsp;SqlSugarScope(new&amp;nbsp;ConnectionConfig()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ConnectionString&amp;nbsp;=&amp;nbsp;&amp;quot;Provider=Microsoft.Jet.OleDb.4.0;Data&amp;nbsp;Source=test.mdb;Persist&amp;nbsp;Security&amp;nbsp;Info=False;Password=;&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DbType&amp;nbsp;=&amp;nbsp;DbType.Access,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IsAutoCloseConnection&amp;nbsp;=&amp;nbsp;true
},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client.Aop.OnError&amp;nbsp;=&amp;nbsp;(ex)&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client.Aop.OnLogExecuting&amp;nbsp;=&amp;nbsp;(sql,&amp;nbsp;pars)&amp;nbsp;=&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;sqlRaw&amp;nbsp;=&amp;nbsp;UtilMethods.GetSqlString(DbType.Access,&amp;nbsp;sql,&amp;nbsp;pars);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Thu, 20 Feb 2025 18:37:02 +0800</pubDate></item></channel></rss>