关于授权认证当下比较流行的框架非IdentityServer莫属,最近抽空学习了下,IdentityServer4是基于openid+auth2.0基础实现的一整套完善的授权中心
相信auth2.0的授权协议相信大家都有了解,不懂的可以参考博客园大佬的文章,讲解的比较详细
阮一峰auth2.0博客
auth2.0仅仅是提供授权认证服务,仅仅提供访问Token,但是如果需要得到授权者的相关用户信息,则需要再次调用UserInfo接口才可以实现,故而OpenID Connect应运而生,它会额外提供Id Token提供用户身份信息,可以少调用一次UserInfo接口(这样是不是很香),大家又会问OpenID Connect是什么东西,其实大家只要搞明白两点就可以了
1. OAuth 2.0是有关如何颁发访问令牌的规范,提供Access Token用于访问服务接口的
2. OpenID Connect是有关如何发行ID令牌的规范,提供Id Token用于用户身份标识,Id Token是基于JWT格式
今天给大家在.NET5环境下构建授权中心,首先需要安装
Microsoft Visual Studio Enterprise 2019
版本 16.8.1
Nuete引用 IdentityServer4.1.1 版本
- 首先搭建IdentityServer授权服务中心
最初了解IdentityServer之前不知道有这个区别,是看到网上有人介绍后,今天特别强调一下
由于IdentityServer4的4.x版本,跟老版本的稍微有些差别:
4.x版本的ApiScope和ApiResource是分开配置的,然后在ApiResource中一定要添加Scopes。如果你在网上搜的IdentityServer4博客论文可能比较老,都是没有介绍ApiScope的代码,老版本默认ApiResource的Name作为Scope。
老版本代码类似这样:
public static IEnumerable<ApiResource> ApiResources =>
new ApiResource[]
{
new ApiResource("api1","第一个api"), // 老版本此处默认将api1作为scope了
};
public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
......
AllowedScopes = { "api1" }
},
};
以上代码访问http://localhost:5000/connect/token接口会提示 “Invalid scopes”
## 正确配置做法如下:
IdentityServer4新版本已经将ApiScope和ApiResource分开配置,最终代码如下
项目结构
Startup.cs文件新增代码
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)
{
services.AddControllersWithViews();
services.AddIdentityServer()//Ids4服务
.AddDeveloperSigningCredential()//添加开发人员签名凭据
.AddTestUsers(Config.Users().ToList())
.AddInMemoryIdentityResources(Config.GetIdentityResources()) //添加内存apiresource
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryApiScopes(Config.GetApiScopes())
.AddInMemoryClients(Config.GetClients());//把配置文件的Client配置资源放到内存
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
//启动ids4中间件
app.UseIdentityServer();
// app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Config.cs代码如下
public class Config
{
//下载ids4的依赖:install-package IdentityServer4 -version 2.1.1
// scopes define the resources in your system
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api1", "第一个api接口")
{
//!!!重要
Scopes = { "scope1"}
},
};
}
public static IEnumerable<ApiScope> GetApiScopes()
{
return new List<ApiScope>
{
new ApiScope("scope1"),
};
}
public static IEnumerable<TestUser> Users()
{
return new[]
{
new TestUser
{
SubjectId = "1",
Username = "mail@qq.com",
Password = "password"
}
};
}
// clients want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "app",
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"scope1",
}
}
};
}
}
此时授权服务中心已经运行,可以访问以下接口获取得到ids4默认discovery endpoint(定义了一个服务发现的规范),它定义了一个api( /.well-known/openid-configuration ),这个api返回一个json数据结构,其中包含了一些OIDC中提供的服务以及其支持情况的描述信息,这样可以使得oidc服务的RP可以不再硬编码OIDC服务接口信息。这个api返回的示例信息如下
http://localhost:5000/.well-known/openid-configuration
.well-known/openid-configuration更多介绍
看到截图中包含了接口:http://localhost:5000/connect/token
用postman访问此接口即可获取access token
由于之前配置的GrantTypes.ResourceOwnerPasswordAndClientCredentials模式,同时支持password和client_credentials两种模式访问
- 使用password模式授权,需要UserName,Password参数得到授权:
- 使用client_credentials模式授权,则无需账号密码
希望以上可以给大家带来帮助,最后来一个总结
1. OAuth 2.0是有关如何颁发访问令牌的规范,提供Access Token用于访问服务接口的
2. OpenID Connect是有关如何发行ID令牌的规范,提供Id Token用于用户身份标识(非敏感信息),Id Token是基于JWT格式
3. IdentityServer4服务中心默认提供接口/connect/token获取access token
4. IdentityServer4新版本新增ApiScope配置保护API资源,并使用ApiScope结合策略授权完成了一个简单的权限控制