切换到混合流并且添加API访问

前面的示例中我们开发了API访问和用户认证,现在我们要将两个合并到一起。

OpenID Connect&OAuth 2.0组合的美妙之处是,你可以使用单一协议和与令牌服务进行单一交换来实现这两种功能。

前面的示例中我们使用过了OpenId Connect的隐式流程(implicit flow)。在隐式流程中所有的token都是通过浏览器进行传输,这对于id token来说没有什么问题的,但是现在我们想要请求一个access token。

access token要比id token更敏感一些,并且如果没有什么必要的话我们并不像让它暴露在外部环境中。OpenID Connect包含了一个叫做“混合”流程,这个流程能给予我们上面说的最好的解决方式----id token通过浏览器通道传输,这样客户端可以在做其他工作之前验证它,并且,如果验证成功,客户端会打开一个后端通道来从token service检索acecss token。

修改客户端配置

做这项工作并没有太多需要修改的地方,首先我们先要让客户端使用混合流程,然后我们还想让客户端和API之间执行一些服务端到服务端的调用,在这个过程中并没有用户参与(这个和client credentials流程相似)。这个是通过使用AllowedGrantTypes属性实现的。

下一步我们需要添加一个client secret。这个会在后端通道用来检索access token。

最后,我们也允许客户端拥有了offline_access这个scope的访问权限,这允许请求一个刷新令牌来实现长时间的API访问。

new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials, ClientSecrets =
{
new Secret("secret".Sha256())
}, RedirectUris = { "http://localhost:5002/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" }, AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
},
AllowOfflineAccess = true
};

修改MVC客户端

对于客户端来说变化也不大,asp.net core中的Openid connect handler已经内置了对混合流程的支持,所以我们只需要修改一些配置值。

我们将ClientSecret配置成匹配IdentityServer上面配置的值。添加offline_access和api1这两个scope,并且将resonsetype设置成code id_token(意思就是告诉mvc客户端我要使用混合流程)。

.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies"; options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false; options.ClientId = "mvc";
options.ClientSecret = "secret";
options.ResponseType = "code id_token"; options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Add("api1");
options.Scope.Add("offline_access");
});

当你运行MVC客户端,发现没由什么太大变化,除了确认页面现在多了API和offline access的scope请求。

使用access token

OpenID Connect中间件自动将一些token(目前有id token、access token、refresh token)为你保存好了。这是设置SaveTokens的意义。

从技术上讲,令牌存储在cookie的属性部分中。访问他们最简单的方式就是使用Microsoft.AspNetCore.Authentication这个命名空间。

比方说在你有一个展示claim的视图:

<dt>access token</dt>
<dd>@await ViewContext.HttpContext.GetTokenAsync("access_token")</dd> <dt>refresh token</dt>
<dd>@await ViewContext.HttpContext.GetTokenAsync("refresh_token")</dd>

为了要使用access token去访问API,你需要获取token,然后在HttpClient中设置它:

public async Task<IActionResult> CallApiUsingUserAccessToken()
{
var accessToken = await HttpContext.GetTokenAsync("access_token"); var client = new HttpClient();
client.SetBearerToken(accessToken);
var content = await client.GetStringAsync("http://localhost:5001/identity"); ViewBag.Json = JArray.Parse(content).ToString();
return View("json");
}

最新文章

  1. 基本 sql语句
  2. java-首字母大小写
  3. OpenGL 小游戏 贪吃蛇1(2D)
  4. [Leetcode][JAVA] Populating Next Right Pointers in Each Node II
  5. Autosizer应用程序窗口控制工具
  6. 备份和还原SQL Server及压缩Access数据库
  7. tomcat项目发布 更改小猫图标 及自定义错误404界面
  8. Cron和Spring定时任务
  9. iMAC——全新重装Mac系统
  10. 学点PYTHON基础的东东--数据结构,算法,设计模式---单向链表
  11. jquery 滚动加载
  12. Linux串口编程详解(转)
  13. hdu5172(线段树)
  14. 记第一届 CCCC-团体程序设计天梯赛决赛 参赛
  15. Android NDK开发及调用标准linux动态库.so文件
  16. Spring aop切面插入事物回滚
  17. Spring DelegatingFilterProxy解析
  18. 项目Alpha冲刺Day4
  19. des加密算法java&amp;c#
  20. blender show normals

热门文章

  1. dicom学习文章
  2. linux crontab定时器
  3. ElasticSearch(二):允许外网连接服务配置
  4. 在JS中调用CS里的方法(PageMethods)
  5. Redo丢失的4种情况及处理方法
  6. Java NIO4:缓冲区Buffer(续)
  7. Spring整合ActiveMQ及多个Queue消息监听的配置
  8. java 加密 解密 Illegal key size
  9. Java线程池实现原理与技术(ThreadPoolExecutor、Executors)
  10. Go+Python双剑合璧