Xamarin与 IdentityServer 认证与授权
认证与授权
2017/08/08
19分钟阅读
+1
身份验证是从用户那里获取身份凭证(例如名称和密码),然后根据权限验证这些凭证的过程。如果凭据有效,则提交凭据的实体将被视为经过身份验证的身份。身份经过身份验证后,授权过程将确定该身份是否有权访问给定资源。
有很多方法可以将身份验证和授权集成到与ASP.NET MVC Web应用程序通信的Xamarin.Forms应用程序中,包括使用ASP.NET Core Identity,外部身份验证提供程序(例如Microsoft,Google,Facebook或Twitter)以及身份验证中间件。eShopOnContainers移动应用程序使用使用IdentityServer 4的容器化身份微服务执行身份验证和授权。移动应用程序向IdentityServer请求安全令牌,以用于认证用户或访问资源。为了使IdentityServer代表用户发行令牌,该用户必须登录到IdentityServer。但是,IdentityServer不提供用于认证的用户界面或数据库。因此,在eShopOnContainers参考应用程序中,ASP。
认证方式
当应用程序需要知道当前用户的身份时,需要进行身份验证。ASP.NET Core识别用户的主要机制是ASP.NET Core Identity成员资格系统,该系统将用户信息存储在开发人员配置的数据存储中。通常,此数据存储区将是EntityFramework存储区,尽管自定义存储区或第三方程序包可用于在Azure存储区,Azure Cosmos DB或其他位置中存储身份信息。
对于使用本地用户数据存储并通过cookie在请求之间保留身份信息的身份验证方案(这在ASP.NET MVC Web应用程序中很常见),ASP.NET Core Identity是合适的解决方案。但是,Cookie并非始终是保留和传输数据的自然方法。例如,公开从移动应用程序访问的RESTful终结点的ASP.NET Core Web应用程序通常将需要使用承载令牌身份验证,因为在这种情况下无法使用Cookie。但是,不记名令牌可以轻松地检索并包含在从移动应用发出的Web请求的授权标头中。
使用IdentityServer 4发行承载令牌
IdentityServer 4是用于ASP.NET Core的开源OpenID Connect和OAuth 2.0框架,可用于许多身份验证和授权方案,包括为本地ASP.NET Core Identity用户颁发安全令牌。
注意
OpenID Connect和OAuth 2.0非常相似,但职责不同。
OpenID Connect是OAuth 2.0协议之上的身份验证层。OAuth 2是一种协议,允许应用程序从安全令牌服务请求访问令牌并使用它们与API通信。由于可以集中身份验证和授权,因此这种委派降低了客户端应用程序和API的复杂性。
OpenID Connect和OAuth 2.0的组合结合了身份验证和API访问的两个基本安全问题,IdentityServer 4是这些协议的实现。
在使用直接客户端到微服务通信的应用程序(例如eShopOnContainers参考应用程序)中,可以使用充当安全令牌服务(STS)的专用身份验证微服务来对用户进行身份验证,如图9-1所示。有关直接的客户端到微服务通信的更多信息,请参阅客户端和微服务之间的通信。
图9-1:通过专用身份验证微服务进行身份验证
eShopOnContainers移动应用程序与身份微服务进行通信,身份微服务使用IdentityServer 4进行身份验证和对API的访问控制。因此,移动应用程序从IdentityServer请求令牌,以用于认证用户或访问资源:
使用IdentityServer对用户进行身份验证是通过移动应用程序请求身份令牌来完成的,该身份令牌表示身份验证过程的结果。它至少包含用户的标识符,以及有关用户进行身份验证的方式和时间的信息。它还可以包含其他身份数据。
通过Identity Server访问Identity是通过移动应用程序请求访问令牌来实现的,该访问令牌允许访问API资源。客户端请求访问令牌并将其转发到API。访问令牌包含有关客户端和用户(如果有)的信息。然后,API使用该信息来授权对其数据的访问。
注意
客户端必须先向IdentityServer注册,然后才能请求令牌。
将IdentityServer添加到Web应用程序
为了使ASP.NET Core Web应用程序使用IdentityServer 4,必须将其添加到Web应用程序的Visual Studio解决方案中。有关更多信息,请参见IdentityServer文档中的概述。
IdentityServer一旦包含在Web应用程序的Visual Studio解决方案中,就必须将其添加到Web应用程序的HTTP请求处理管道中,以便它可以为OpenID Connect和OAuth 2.0端点提供请求。如下面的代码示例所示,这是通过ConfigureWeb应用程序Startup类中的方法实现的:
C#
复制
public void Configure(
IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
app.UseIdentity();
...
}
顺序在Web应用程序的HTTP请求处理管道中很重要。因此,必须在实现登录屏幕的UI框架之前将IdentityServer添加到管道中。
配置IdentityServer
应该通过调用该方法ConfigureServices在Web应用程序Startup类中的方法中配置IdentityServer services.AddIdentityServer,如eShopOnContainers参考应用程序中的以下代码示例所示:
C#
复制
public void ConfigureServices(IServiceCollection services)
{
...
services.AddIdentityServer(x => x.IssuerUri = "null")
.AddSigningCredential(Certificate.Get())
.AddAspNetIdentity<ApplicationUser>()
.AddConfigurationStore(builder =>
builder.UseSqlServer(connectionString, options =>
options.MigrationsAssembly(migrationsAssembly)))
.AddOperationalStore(builder =>
builder.UseSqlServer(connectionString, options =>
options.MigrationsAssembly(migrationsAssembly)))
.Services.AddTransient<IProfileService, ProfileService>();
}
调用该services.AddIdentityServer方法后,将调用其他流利的API来配置以下内容:
用于签名的凭据。
用户可能请求访问的API和身份资源。
将连接到请求令牌的客户端。
ASP.NET核心身份。
小费
动态加载IdentityServer 4配置。IdentityServer 4的API允许从内存中的配置对象列表中配置IdentityServer。在eShopOnContainers参考应用程序中,这些内存中的集合被硬编码到应用程序中。但是,在生产方案中,可以从配置文件或数据库中动态加载它们。
有关将IdentityServer配置为使用ASP.NET Core身份的信息,请参阅IdentityServer文档中的使用ASP.NET Core身份。
配置API资源
在配置API资源时,该AddInMemoryApiResources方法需要一个IEnumerable<ApiResource>集合。以下代码示例显示了GetApis在eShopOnContainers参考应用程序中提供此集合的方法:
C#
复制
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("orders", "Orders Service"),
new ApiResource("basket", "Basket Service")
};
}
此方法指定IdentityServer应该保护订单和购物篮API。因此,在调用这些API时将需要IdentityServer管理的访问令牌。有关ApiResource类型的更多信息,请参见IdentityServer 4文档中的API资源。
配置身份资源
配置身份资源时,该AddInMemoryIdentityResources方法需要IEnumerable<IdentityResource>收集。身份资源是诸如用户ID,名称或电子邮件地址之类的数据。每个身份资源都有一个唯一的名称,可以为它分配任意声明类型,然后将其包含在用户的身份令牌中。以下代码示例显示了GetResources在eShopOnContainers参考应用程序中提供此集合的方法:
C#
复制
public static IEnumerable<IdentityResource> GetResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
}
OpenID Connect规范指定了一些标准标识资源。最低要求是提供支持为用户发出唯一ID。这是通过公开IdentityResources.OpenId身份资源来实现的。
注意
该IdentityResources级支持所有的ID连接规范(OpenID的,电子邮件,个人资料,电话和地址)所定义的范围的。
IdentityServer还支持定义自定义身份资源。有关更多信息,请参见IdentityServer文档中的定义自定义身份资源。有关IdentityResource类型的更多信息,请参见IdentityServer 4文档中的身份资源。
配置客户端
客户端是可以从IdentityServer请求令牌的应用程序。通常,必须至少为每个客户端定义以下设置:
唯一的客户端ID。
允许与令牌服务的交互(称为授予类型)。
身份和访问令牌发送到的位置(称为重定向URI)。
允许客户端访问的资源列表(称为作用域)。
配置客户端时,该AddInMemoryClients方法需要IEnumerable<Client>收集。以下代码示例显示了GetClients在eShopOnContainers参考应用程序中提供此集合的方法中eShopOnContainers移动应用程序的配置:
C#
复制
public static IEnumerable<Client> GetClients(Dictionary<string,string> clientsUrl)
{
return new List<Client>
{
...
new Client
{
ClientId = "xamarin",
ClientName = "eShop Xamarin OpenId Client",
AllowedGrantTypes = GrantTypes.Hybrid,
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = { clientsUrl["Xamarin"] },
RequireConsent = false,
RequirePkce = true,
PostLogoutRedirectUris = { $"{clientsUrl["Xamarin"]}/Account/Redirecting" },
AllowedCorsOrigins = { "http://eshopxamarin" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess,
"orders",
"basket"
},
AllowOfflineAccess = true,
AllowAccessTokensViaBrowser = true
},
...
};
}
此配置为以下属性指定数据:
ClientId:客户端的唯一ID。
ClientName:客户端显示名称,用于日志记录和同意屏幕。
AllowedGrantTypes:指定客户端希望如何与IdentityServer交互。有关更多信息,请参阅配置身份验证流程。
ClientSecrets:指定从令牌端点请求令牌时使用的客户端机密凭据。
RedirectUris:指定允许令牌或授权码返回的URI。
RequireConsent:指定是否需要同意屏幕。
RequirePkce:指定使用授权码的客户端是否必须发送证明密钥。
PostLogoutRedirectUris:指定注销后重定向到的允许URI。
AllowedCorsOrigins:指定客户端的来源,以便IdentityServer可以允许来自来源的跨域调用。
AllowedScopes:指定客户端可以访问的资源。默认情况下,客户端无权访问任何资源。
AllowOfflineAccess:指定客户端是否可以请求刷新令牌。
配置认证流程
可以通过在Client.AllowedGrantTypes属性中指定授予类型来配置客户端和IdentityServer之间的身份验证流。OpenID Connect和OAuth 2.0规范定义了许多身份验证流程,包括:
隐式的 该流程针对基于浏览器的应用程序进行了优化,应用于仅用户身份验证或身份验证和访问令牌请求。所有令牌都是通过浏览器传输的,因此不允许使用高级功能(例如刷新令牌)。
授权码。与浏览器前端通道相反,此流程提供了在后端通道上检索令牌的能力,同时还支持客户端身份验证。
混合动力车 此流程是隐式和授权代码授予类型的组合。身份令牌通过浏览器通道传输,并包含签名的协议响应以及其他工件(例如授权码)。成功验证响应后,应使用反向通道来检索访问和刷新令牌。
小费
使用混合身份验证流程。混合身份验证流减轻了适用于浏览器通道的多种攻击,对于希望检索访问令牌(并可能刷新令牌)的本机应用程序,推荐使用混合流。
有关认证流程的更多信息,请参见IdentityServer 4文档中的“ 授予类型 ”。
执行身份验证
为了使IdentityServer代表用户发行令牌,该用户必须登录到IdentityServer。但是,IdentityServer不提供用于认证的用户界面或数据库。因此,在eShopOnContainers参考应用程序中,ASP.NET Core Identity用于此目的。
eShopOnContainers移动应用程序通过混合身份验证流程向IdentityServer进行身份验证,如图9-2所示。
图9-2:登录过程的高级概述
向发出登录请求<base endpoint>:5105/connect/authorize。成功认证后,IdentityServer返回包含授权码和身份令牌的认证响应。然后<base endpoint>:5105/connect/token,将授权码发送到,以响应访问,身份和刷新令牌。
eShopOnContainers移动应用通过向发出<base endpoint>:5105/connect/endsession带有附加参数的请求来注销IdentityServer 。发生注销后,IdentityServer会通过将注销后的重定向URI发送回移动应用程序进行响应。图9-3说明了此过程。
图9-3:注销过程的高级概述
在eShopOnContainers移动应用程序中,与IdentityServer的通信由IdentityService实现IIdentityService接口的类执行。此接口指定的实现类必须提供CreateAuthorizationRequest,CreateLogoutRequest和GetTokenAsync方法。
登录中
当用户轻敲LOGIN上的按钮LoginView时,SignInCommand在LoginViewModel类执行时,这反过来执行该SignInAsync方法。以下代码示例显示了此方法:
C#
复制
private async Task SignInAsync()
{
...
LoginUrl = _identityService.CreateAuthorizationRequest();
IsLogin = true;
...
}
此方法调用类中的CreateAuthorizationRequest方法,IdentityService如下面的代码示例所示:
C#
复制
public string CreateAuthorizationRequest()
{
// Create URI to authorization endpoint
var authorizeRequest = new AuthorizeRequest(GlobalSetting.Instance.IdentityEndpoint);
// Dictionary with values for the authorize request
var dic = new Dictionary<string, string>();
dic.Add("client_id", GlobalSetting.Instance.ClientId);
dic.Add("client_secret", GlobalSetting.Instance.ClientSecret);
dic.Add("response_type", "code id_token");
dic.Add("scope", "openid profile basket orders locations marketing offline_access");
dic.Add("redirect_uri", GlobalSetting.Instance.Callback);
dic.Add("nonce", Guid.NewGuid().ToString("N"));
dic.Add("code_challenge", CreateCodeChallenge());
dic.Add("code_challenge_method", "S256");
// Add CSRF token to protect against cross-site request forgery attacks.
var currentCSRFToken = Guid.NewGuid().ToString("N");
dic.Add("state", currentCSRFToken);
var authorizeUri = authorizeRequest.Create(dic);
return authorizeUri;
}
此方法使用必需的参数为IdentityServer的授权端点创建URI 。授权端点位于/connect/authorize作为用户设置公开的基本端点的端口5105上。有关用户设置的更多信息,请参阅Configuration Management。
注意
通过对OAuth实施代码交换证明密钥(PKCE)扩展,可以减少eShopOnContainers移动应用程序的攻击面。PKCE可以防止授权码被截获时被使用。这是通过客户端生成一个秘密验证程序来实现的,该验证程序的哈希在授权请求中传递,并且在赎回授权代码时不会显示为散列。有关PKCE的更多信息,请参阅Internet工程任务组网站上的OAuth公共客户端进行代码交换的证明密钥。
返回的URI存储在类的LoginUrl属性中LoginViewModel。当IsLogin属性变为时true,中的WebView中的LoginView变为可见。该WebView数据绑定的Source属性为LoginUrl的财产LoginViewModel类,所以使得登录请求IdentityServer当LoginUrl属性设置为IdentityServer的授权端点。当IdentityServer收到此请求并且用户未通过身份验证时,WebView它将被重定向到配置的登录页面,如图9-4所示。
图9-4: WebView显示的登录页面
登录完成后,WebView将重定向到返回URI。此WebView导航将导致执行该类中的NavigateAsync方法,LoginViewModel如以下代码示例所示:
C#
复制
private async Task NavigateAsync(string url)
{
...
var authResponse = new AuthorizeResponse(url);
if (!string.IsNullOrWhiteSpace(authResponse.Code))
{
var userToken = await _identityService.GetTokenAsync(authResponse.Code);
string accessToken = userToken.AccessToken;
if (!string.IsNullOrWhiteSpace(accessToken))
{
Settings.AuthAccessToken = accessToken;
Settings.AuthIdToken = authResponse.IdentityToken;
await NavigationService.NavigateToAsync<MainViewModel>();
await NavigationService.RemoveLastFromBackStackAsync();
}
}
...
}
此方法解析包含在返回URI中的身份验证响应,并假设存在有效的授权代码,则此方法向IdentityServer的令牌端点发出请求,并传递授权代码,PKCE秘密验证程序和其他必需的参数。令牌端点位于/connect/token作为用户设置公开的基本端点的端口5105上。有关用户设置的更多信息,请参阅Configuration Management。
小费
验证返回URI。尽管eShopOnContainers移动应用程序不验证返回URI,但是最佳实践是验证返回URI指向已知位置,以防止打开重定向攻击。
如果令牌端点接收到有效的授权码和PKCE秘密验证者,它将以访问令牌,身份令牌和刷新令牌进行响应。然后,将访问令牌(允许访问API资源)和身份令牌存储为应用程序设置,并执行页面导航。因此,eShopOnContainers移动应用程序的总体效果是:只要用户能够通过IdentityServer成功进行身份验证,就可以将他们导航到该MainView页面,该页面TabbedPage将显示CatalogView为选定选项卡。
有关页面导航的信息,请参见导航。有关WebView导航如何导致视图模型方法被执行的信息,请参阅《使用行为调用导航》。有关应用程序设置的信息,请参阅《配置管理》。
注意
当应用程序配置为在中使用模拟服务时,eShopOnContainers还允许模拟登录SettingsView。在这种模式下,该应用程序不与IdentityServer通信,而是允许用户使用任何凭据登录。
登出
当用户轻敲LOG OUT在按钮ProfileView时,LogoutCommand在ProfileViewModel类执行时,这反过来执行该LogoutAsync方法。此方法LoginView通过将LogoutParameter设置为的实例true作为参数传递到页面。有关在页面导航期间传递参数的更多信息,请参见导航期间传递参数。
创建视图并导航到InitializeAsync该视图时,将执行该视图的关联视图模型的Logout方法,然后执行LoginViewModel该类的方法,如以下代码示例所示:
C#
复制
private void Logout()
{
var authIdToken = Settings.AuthIdToken;
var logoutRequest = _identityService.CreateLogoutRequest(authIdToken);
if (!string.IsNullOrEmpty(logoutRequest))
{
// Logout
LoginUrl = logoutRequest;
}
...
}
此方法调用类中的CreateLogoutRequest方法IdentityService,并将从应用程序设置中检索到的标识令牌作为参数传递。有关应用程序设置的更多信息,请参阅Configuration Management。以下代码示例显示了该CreateLogoutRequest方法:
C#
复制
public string CreateLogoutRequest(string token)
{
...
return string.Format("{0}?id_token_hint={1}&post_logout_redirect_uri={2}",
GlobalSetting.Instance.LogoutEndpoint,
token,
GlobalSetting.Instance.LogoutCallback);
}
此方法使用必需的参数创建到IdentityServer的结束会话终结点的URI 。结束会话终结点位于/connect/endsession作为用户设置公开的基本终结点的端口5105上。有关用户设置的更多信息,请参阅Configuration Management。
返回的URI存储在类的LoginUrl属性中LoginViewModel。当IsLogin属性为时true,中的WebView中将LoginView可见。该WebView数据绑定的Source属性为LoginUrl的财产LoginViewModel类,所以使得签出请求到IdentityServer当LoginUrl属性设置为IdentityServer结束会话端点。当IdentityServer收到此请求时,只要用户已登录,就会发生注销。使用由ASP.NET Core的cookie身份验证中间件管理的cookie跟踪身份验证。因此,注销IdentityServer将删除身份验证cookie,并将注销后的重定向URI发送回客户端。
在移动应用中,WebView将被重定向到登出后重定向URI。此WebView导航将导致执行该类中的NavigateAsync方法,LoginViewModel如以下代码示例所示:
C#
复制
private async Task NavigateAsync(string url)
{
...
Settings.AuthAccessToken = string.Empty;
Settings.AuthIdToken = string.Empty;
IsLogin = false;
LoginUrl = _identityService.CreateAuthorizationRequest();
...
}
此方法清除这两个令牌身份和应用程序设置令牌的访问,并设置IsLogin属性false,从而导致WebView了对LoginView网页,成为无形的。最后,使用所需参数将LoginUrl属性设置为IdentityServer 授权端点的URI,以为用户下次启动登录做准备。
有关页面导航的信息,请参见导航。有关WebView导航如何导致视图模型方法被执行的信息,请参阅《使用行为调用导航》。有关应用程序设置的信息,请参阅《配置管理》。
注意
当应用程序配置为在SettingsView中使用模拟服务时,eShopOnContainers还允许模拟退出。在这种模式下,应用程序不与IdentityServer通信,而是从应用程序设置中清除所有存储的令牌。
授权书
进行身份验证后,ASP.NET Core Web API通常需要授权访问权限,这使服务可以使某些身份验证的用户(而非全部)可以使用API。
可以通过对控制器或操作应用Authorize属性来限制对ASP.NET Core MVC路由的访问,这将对经过验证的用户的控制器或操作的访问限制为如下代码示例所示:
C#
复制
[Authorize]
public class BasketController : Controller
{
...
}
如果未经授权的用户尝试访问带有该Authorize属性标记的控制器或操作,则MVC框架将返回401(未经授权)的HTTP状态代码。
注意
可以在Authorize属性上指定参数,以将API限制为特定用户。有关更多信息,请参见授权。
IdentityServer可以集成到授权工作流程中,以便它提供的访问令牌可以控制授权。这种方法如图9-5所示。
图9-5:通过访问令牌进行授权
eShopOnContainers移动应用程序与身份微服务进行通信,并在身份验证过程中请求访问令牌。然后,将访问令牌转发给订购和购物篮微服务所公开的API,作为访问请求的一部分。访问令牌包含有关客户端和用户的信息。然后,API使用该信息来授权对其数据的访问。有关如何配置IdentityServer以保护API的信息,请参见“ 配置API资源”。
配置IdentityServer执行授权
要使用IdentityServer执行授权,必须将其授权中间件添加到Web应用程序的HTTP请求管道中。中间件被添加ConfigureAuth到Web应用程序Startup类的方法中,该中间件从该Configure方法中调用,并在eShopOnContainers参考应用程序的以下代码示例中进行了演示:
C#
复制
protected virtual void ConfigureAuth(IApplicationBuilder app)
{
var identityUrl = Configuration.GetValue<string>("IdentityUrl");
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = identityUrl.ToString(),
ScopeName = "basket",
RequireHttpsMetadata = false
});
}
此方法确保只能使用有效的访问令牌来访问API。中间件验证传入的令牌以确保它是从受信任的发行者发送的,并验证令牌是否有效以与接收它的API一起使用。因此,浏览到订购或购物篮控制器将返回401(未授权)HTTP状态代码,指示需要访问令牌。
注意
在使用app.UseMvc()或添加MVC之前,必须将IdentityServer的授权中间件添加到Web应用程序的HTTP请求管道中app.UseMvcWithDefaultRoute()。
向API发出访问请求
向订购和购物篮微服务发出请求时,在身份验证过程中从IdentityServer获得的访问令牌必须包含在请求中,如以下代码示例所示:
C#
复制
var authToken = Settings.AuthAccessToken;
Order = await _ordersService.GetOrderAsync(Convert.ToInt32(order.OrderNumber), authToken);
访问令牌存储为应用程序设置,并从特定于平台的存储中检索,并包含GetOrderAsync在对该OrderService类中方法的调用中。
同样,将数据发送到受IdentityServer保护的API时,必须包含访问令牌,如以下代码示例所示:
C#
复制
var authToken = Settings.AuthAccessToken;
await _basketService.UpdateBasketAsync(new CustomerBasket
{
BuyerId = userInfo.UserId,
Items = BasketItems.ToList()
}, authToken);
访问令牌是从特定于平台的存储中检索的,并包含UpdateBasketAsync在对该BasketService类中方法的调用中。
该RequestProvider班,在eShopOnContainers移动应用程序,使用HttpClient类,以便请求由eShopOnContainers参考应用暴露了RESTful API中。向需要授权的订购和购物篮API发出请求时,请求中必须包含有效的访问令牌。这是通过将访问令牌添加到HttpClient实例的标头来实现的,如以下代码示例所示:
C#
复制
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
该类的DefaultRequestHeaders属性HttpClient公开随每个请求发送的标头,并将访问令牌添加到Authorization以string为前缀的标头中Bearer。将请求发送到RESTful API时,将Authorization提取并验证标头的值以确保它是从受信任的颁发者发送的,并用于确定用户是否有权调用接收该标头的API。
有关eShopOnContainers移动应用如何发出Web请求的更多信息,请参阅访问远程数据。
摘要
有很多方法可以将身份验证和授权集成到与ASP.NET MVC Web应用程序通信的Xamarin.Forms应用程序中。eShopOnContainers移动应用程序使用使用IdentityServer 4的容器化身份微服务执行身份验证和授权。IdentityServer是用于ASP.NET Core的开源OpenID Connect和OAuth 2.0框架,该框架与ASP.NET Core Identity集成以执行承载令牌身份验证。
移动应用程序从IdentityServer请求安全令牌,以用于认证用户或访问资源。访问资源时,访问令牌必须包含在对需要授权的API的请求中。IdentityServer的中间件验证传入的访问令牌,以确保它们是从受信任的颁发者发送的,并且可以与接收它们的API一起使用。
相关链接
下载电子书(2Mb PDF)
eShopOnContainers(GitHub)(示例)
浙公网安备 33010602011771号