IdentityServer4在Asp.Net Core中的应用(三)
今天的内容是授权模式中的简化模式,还是先看以下授权流程图:
在这种模式中我们将与OpenID结合使用,所以首先我们要了解OpenID和OAuth的区别,关于他们的区别,在我上一篇博客《理解OpenID和OAuth的区别》中做了的一些简要的介绍,这里不再多说。
授权服务器我们还是在之前的基础上改动,首先我们需要在Config类里面添加对OpenID Connect Identity Scopes的支持,与OAuth2.0相比,OIDC(OpenID Connect)同样需要Scopes的概念,他也需要保护Scopes范围的内容而也需要让用户去访问的内容,但是OIDC中这里的范围并不是用户要访问的API,而是用户标识、用户名、Email等信息。
添加对OpenId(SubjectId) Profile(first name last name etc...)的支持范围,并返回一个IdentityReSource的集合,添加以下代码:
//添加对OpenID Profile范围的支持
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
再天际一个客户端,基于Implicit授权模式,添加以下代码:
new Client(){
ClientId="impClient",
AllowedGrantTypes=GrantTypes.Implicit,
//用于登录成功后的RedirectUri
RedirectUris={"http://localhost:5004/signin-oidc"},
//用于注销后的RedirectUri
PostLogoutRedirectUris={"http://localhost:5004/signout-callback-oidc"},
//允许访问的范围
AllowedScopes={
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
}
}
下面我们还要将IdentityResource注入到IdentityServer中,在ConfigureService中,添加:
.AddInMemoryIdentityResources(Config.GetIdentityResources())
修改返回的TestUser的方法,在每一个用户中添加一个声明属性的集合,返回一个name和address信息,改动如下:
return new List<TestUser>{
new TestUser(){
SubjectId="1",
Username="allen",
Password="123456",
Claims=new List<Claim>
{
new Claim("name","Allen"),
new Claim("address","http://allen.com")
}
},
new TestUser(){
SubjectId="2",
Username="alisa",
Password="123456",
Claims=new List<Claim>
{
new Claim("name","Alisa"),
new Claim("address","http://alisa.com")
}
}
OIDC所需的所有协议已经内置在IdentityServer4中了,需要为登录、注销、同意授权内容以及错误等提供UI的部分,IdentityServer4提供了一个简单的基于MVC的UI界面,我们可以直接download到我们的服务端里,在控制台使用命令:
如果你是Windows系统,使用以下命令:
iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/release/get.ps1'))
如果你是MacOS或者Linux用户,使用:
\curl -L https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/release/get.sh | bash
执行完成后,会发现多了一个QuickStart文件夹,放置了所用到的Controller,Views文件夹下也放置了对应的视图,
由于我创建的是WebApi项目,所以还要在StartUp.cs里面将原来我们注释掉的app.UseMvc()解开,另外在配置默认路由前还要添加使用静态文件,以使用我们的静态文件夹下的样式,app.UseStaticFiles(); 以上内容都修改完成后,下面我们新建一个Mvc的项目,去请求我们的授权服务器,如何创建不再赘述,创建完成后添加对OIDC认证的支持,在ConfigureServices的方法中添加以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.IdentityModel.Tokens.Jwt; namespace MvcClient
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); //添加认证服务到DI中,
services.AddAuthentication(options=>{
//使用Cookies作为唯一的认证用户的主要手段
options.DefaultScheme="Cookies";
//需要用户登录才可进入该应用程序,使用OpenID Connect scheme
options.DefaultChallengeScheme="oidc";
})
//添加可以处理Cookie的处理程序
.AddCookie("Cookies") //配置OpenID Connect协议
.AddOpenIdConnect("oidc",options=>{
//OIDC协议执行完成,发布Cookie
options.SignInScheme="Cookies"; //授权服务器地址
options.Authority="http://localhost:5000";
options.RequireHttpsMetadata=false;
//指定客户端Id
options.ClientId="impClient";
//保存令牌在Cookie中
options.SaveTokens=true;
}); services.AddMvc();
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (!env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles(); //添加认证中间件
app.UseAuthentication(); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
注意配置启动时将MvcClient启动端口改为5004,因为我在服务端指定的客户端的端口为5004,接着我们添加一个Action,使他需要进行授权访问,
[Authorize]
public IActionResult Authorize()
{
return View();
}
并添加对应的视图,展示用户信息:
@{
ViewData["Title"] = "Authorize";
}
<h2>Claims:</h2>
<dl>
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>
}
</dl>
至此,我们的配置就完成了,下面我们运行看下效果,首先run下服务端,再启动我们的客户端,客户端点击Authorize菜单:
这个就对应我们那个需要QQ登录的界面了,需要通过认证,我们输入我们事先配置的用户名和密码,allen 123456,
到consent页面是要通过我们的授权,将我们用户信息共享给客户端,现在我们选择用户profile,点击允许:
当我们点击不允许读取用户信息的时候:
在不允许读取的情况下,我们是无法看到用户名的。下面我们再添加一个注销登录的方法,
//注销登录
public async Task LogOut()
{
await HttpContext.SignOutAsync("Cookies");
await HttpContext.SignOutAsync("oidc");
}
执行退出:
至此整个Implicit授权模式的过程就进行完了。
扫描二维码关注我的公众号,共同学习,共同进步!
IdentityServer4在Asp.Net Core中的应用(三)的更多相关文章
- IdentityServer4在Asp.Net Core中的应用(一)
IdentityServer4是一套身份授权以及访问控制的解决方案,专注于帮助使用.Net 技术的公司为现代应用程序建立标识和访问控制解决方案,包括单点登录.身份管理.授权和API安全. 下面我将具体 ...
- IdentityServer4在Asp.Net Core中的应用(二)
继续上次授权的内容,客户端模式后我们再说以下密码模式,先回顾下密码模式的流程: 我们还是使用上次的代码,在那基础上修改,在IdentityServer4里面有一个IdentityServer4.Tes ...
- Asp.Net Core 中IdentityServer4 授权中心之应用实战
一.前言 查阅了大多数相关资料,查阅到的IdentityServer4 的相关文章大多是比较简单并且多是翻译官网的文档编写的,我这里在 Asp.Net Core 中IdentityServer4 的应 ...
- Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式
一.前言 上一篇我分享了一篇关于 Asp.Net Core 中IdentityServer4 授权中心之应用实战 的文章,其中有不少博友给我提了问题,其中有一个博友问我的一个场景,我给他解答的还不够完 ...
- Asp.Net Core 中IdentityServer4 授权原理及刷新Token的应用
一.前言 上面分享了IdentityServer4 两篇系列文章,核心主题主要是密码授权模式及自定义授权模式,但是仅仅是分享了这两种模式的使用,这篇文章进一步来分享IdentityServer4的授权 ...
- Asp.Net Core 中IdentityServer4 实战之 Claim详解
一.前言 由于疫情原因,让我开始了以博客的方式来学习和分享技术(持续分享的过程也是自己学习成长的过程),同时也让更多的初学者学习到相关知识,如果我的文章中有分析不到位的地方,还请大家多多指教:以后我会 ...
- Asp.Net Core 中IdentityServer4 实战之角色授权详解
一.前言 前几篇文章分享了IdentityServer4密码模式的基本授权及自定义授权等方式,最近由于改造一个网关服务,用到了IdentityServer4的授权,改造过程中发现比较适合基于Role角 ...
- 大话IdentityServer4之使用 IdentityServer4 保护 ASP.NET Core 应用
这几天一直在研究IdentityServer4在asp.net core3.0中的应用,下面说说我的理解: 我们每一个.net core 项目大家可以理解为我新建了一个动物园或者植物园等,注册用户想要 ...
- 从零搭建一个IdentityServer——聊聊Asp.net core中的身份验证与授权
OpenIDConnect是一个身份验证服务,而Oauth2.0是一个授权框架,在前面几篇文章里通过IdentityServer4实现了基于Oauth2.0的客户端证书(Client_Credenti ...
随机推荐
- PAT 1120 Friend Numbers[简单]
1120 Friend Numbers (20 分) Two integers are called "friend numbers" if they share the same ...
- 模块讲解----os
os:跟操作系统相关的信息 os模块的增删改查 一.cd进入: windowd: os.chdir("D:/软件/pychar/data/s13") print('获取当前位置:' ...
- Linux系统——特殊符号、通配符及正则表达式
特殊符号 | 管道符号,将管道符左边的命令的执行结果以字符串的形式通过 管道符传送到管道符右边命令末尾,作为管道符右边命令的执行 范围 > 输出重定向 >> 追加输出重定向 < ...
- PL/SQL 创建用户及权限操作
1.创建User create user user01 identified by user01, 2.赋予连接数据库的权限 grant connect to user01; 3.把user00的表E ...
- 将jar包发布到nexus仓库
版本的快速迭代不适合release发布到仓库,snapshot方便版本的快速迭代. 1.pom改为snapshot <dependency> <groupId>com.sf.c ...
- Restful风格API
一:协议 API与用户的通信协议,总是使用HTTPS协议. 二:域名 应该尽量将API部署在专用域名之下. https://api.example.com 如果确定API很简单,不会有进一步扩展,可以 ...
- Java线程常用方法汇总
1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据.注意该方 ...
- 20145316《Java程序设计》实验一:Java开发环境的熟悉(Windows + IDEA)
20145316<Java程序设计>实验一:Java开发环境的熟悉(Windows + IDEA) 一.DOC命令行下Java程序开发 1.打开cmd,输入 mkdir 20145316命 ...
- Base64转Blob
最近碰见一个问题,a链接的href为base64,但在chrome下载时显示下载失败,经查询,base64过大会在某些浏览器上下载失败(如新版chrome),解决方法是将base64转为blob fu ...
- linux第四周
一.知识点总结 (一)用户态.内核态和中断 1.内核态:在高的执行级别下,代码可以执行特权指令,访问任意的物理地址,这时的CPU就对应内核态 2.用户态:在低级别的指令状态下,代码 只能在级别允许的特 ...