Identity server 最新版本和vue结合使用的坑(1)
前言
最近由于公司项目重构,要把登录做成单点登录,要用到identity server 及.net core 自带的identity认证身份 此文用作于记录学习identity server最新版本与API、.net core MVC、Javascript 以及vue等结合使用的坑。
首先介绍一下自己用的环境:vs2019、.net core 3.1 sdk、identity server4.0.4(目前官网最新的文档 https://identityserver4.readthedocs.io/en/latest/index.html )、node.js 12.18.3 vue客户端用的是vs code。
新建IdentityServer4服务端
简单来说服务端就是发送token以及验证token并且管理一些相关用户的操作的地方
新建一个ASP.NET Core Web Application 空项目AuthServer
给网站设置默认地址 http://localhost:5000 并且在launchSettings.json文件中删除IIS Express节点以及iisSettings节点,这样删除是为了直接用控制台模式运行并且不用iis。
{ "profiles": { "AuthServer": { "commandName": "Project", "launchBrowser": true, "applicationUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
第一步:添加Nuget包,Identityserver4
添加IdentityServer4 引用:
Install-Package IdentityServer4
第二步:添加config.cs 配置类
public static class Config { /// <summary> /// 身份资源 /// </summary> public static IEnumerable<IdentityResource> GetIdentityResources() { return new List<IdentityResource> { //这里实际是claims的返回资源 new IdentityResources.OpenId(), new IdentityResources.Profile() }; } /// <summary> /// api范围 /// </summary> public static IEnumerable<ApiScope> GetApiScopes() { return new List<ApiScope> { new ApiScope("api1", "GS1 API") }; } /// <summary> /// 需要保护的Api资源 /// </summary> /// <returns></returns> public static List<ApiResource> GetApiResource() { return new List<ApiResource> { new ApiResource("api1","GS1 API") }; } /// <summary> /// 客户端配置 /// </summary> public static IEnumerable<Client> GetClients() { return new List<Client> { // 定义用于服务器到服务器通信的客户端 new Client { ClientId = "client", ClientSecrets = { new Secret("secret".Sha256()) }, AllowedGrantTypes = GrantTypes.ClientCredentials, //这是一种最简单的授权方式,应用于服务于服务之间的通信,token通常代表的是客户端的请求,而不是用户。使用这种授权类型,会向token endpoint发送token请求,并获得代表客户机的access token。客户端通常必须使用token endpoint的Client ID和secret进行身份验证。适用场景:用于和用户无关,服务与服务之间直接交互访问资源 // scopes that client has access to AllowedScopes = { "api1" } }, // 定义一个交互式应用程序以进行使用身份验证和委托的API访问 new Client { ClientId = "mvc", ClientSecrets = { new Secret("secret".Sha256()) }, AllowedGrantTypes = GrantTypes.Code, // where to redirect to after login RedirectUris = { "http://localhost:5002/signin-oidc" },//跳转登录到的客户端的地址 // where to redirect to after logout PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },//跳转登出到的客户端的地址 AllowedScopes = new List<string>//运行访问的资源 { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "api1" }, AlwaysIncludeUserClaimsInIdToken = true, }, // 定义一个 前端应用程序 new Client { ClientId = "js", ClientName = "JavaScript Client", AllowedGrantTypes = GrantTypes.Implicit,//允许的授权类型 AllowAccessTokensViaBrowser = true,//控制是否通过浏览器传输此客户端的访问令牌 RedirectUris = { "http://localhost:9529/callback" }, PostLogoutRedirectUris = { "http://localhost:9529/" }, AllowedCorsOrigins = { "http://localhost:9529" }, AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "api1" }, AlwaysIncludeUserClaimsInIdToken = true,//当同时请求id令牌和访问令牌时,用户应该始终声明添加到id令牌,而不要求客户端使用userinfo端点。 AccessTokenLifetime=60,//访问令牌的生命周期(以秒为单位)(默认值为3600秒/ 1小时) IdentityTokenLifetime=60,//id token 的生命周期 }, new Client { ClientName = "vuejs_code_client", ClientId = "vuejs_code_client", RequirePkce = true, RequireClientSecret = false, AllowedGrantTypes = GrantTypes.Code, AccessTokenLifetime=330,//访问令牌的生命周期(以秒为单位)(默认值为3600秒/ 1小时) IdentityTokenLifetime=300,//id token 的生命周期 AllowOfflineAccess = true,//指示是否[允许脱机访问] RefreshTokenUsage= TokenUsage.OneTimeOnly,//是否复用 RefreshToken ReUse:是 OneTimeOnly:每次生成新的 建议 OneTimeOnly 防止重放攻击 AllowAccessTokensViaBrowser = true, RedirectUris = new List<string> { "http://localhost:5004/callback", }, PostLogoutRedirectUris = new List<string> { "http://localhost:5004/", }, AllowedCorsOrigins = new List<string> { "http://localhost:5004" }, AllowedScopes = new List<string> { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "api1", IdentityServerConstants.StandardScopes.OfflineAccess, }, }, }; } }
填坑:这里identity server4 最新的配置 ApiScope 这个方法是必有的 (不然到时候和客户端对接的时候会有错误) ApiResource这个无所谓 如果你想在客户端设置保护资源的话 这个可以有
第三步:修改starup配置
public void ConfigureServices(IServiceCollection services) { //先是内存测试 后面转换为持久化数据存储 services.AddIdentityServer() .AddDeveloperSigningCredential()//添加开发人员签名凭据 .AddInMemoryApiScopes(Config.GetApiScopes())//添加内存Scopes 必须在AddInMemoryApiResources方法前add .AddInMemoryApiResources(Config.GetApiResource())//添加内存apiresource .AddInMemoryClients(Config.GetClients())//添加内存client .AddInMemoryIdentityResources(Config.GetIdentityResources());//添加系统中的资源 }
Configure方法中添加如下代码 必须在app.UseRouting();与 app.UseEndpoints方法之间调用,否则失效无用
app.UseIdentityServer();//使用identity server中间件 app.UseAuthentication();//使用授权
ok,那我们正常配置identityserver就好了 先f5调试一下 如果成功会默认打开一个浏览器 并且内容为Hello World! 说明我们配置成功了 没有配置成功的 看看哪里细节忽略掉了吧。
那现在我们要做的就是生成一套identity server4 自带的模板出来 官网都有例子 https://github.com/IdentityServer/IdentityServer4.Quickstart.UI/ 那这里我就使用 打开文件地址 用powershell 去执行命令行 让他自己down下来相关模板文件
命令为:iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/main/getmain.ps1')) ok 执行完命令后 我们项目多了三个文件夹 wwwroot、Quickstart以及Views 说明我们执行成功了
然后我们修改一下starup类配置
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); //先是内存测试 后面转换为持久化数据存储 services.AddIdentityServer() .AddDeveloperSigningCredential()//添加开发人员签名凭据 .AddInMemoryApiScopes(Config.GetApiScopes())//添加内存Scopes 必须在AddInMemoryApiResources方法前add .AddInMemoryApiResources(Config.GetApiResource())//添加内存apiresource .AddInMemoryClients(Config.GetClients())//添加内存client .AddInMemoryIdentityResources(Config.GetIdentityResources());//添加系统中的资源 } // 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(); } app.UseStaticFiles();//使用静态文件 app.UseRouting(); app.UseIdentityServer();//使用identity server中间件 app.UseAuthentication();//使用授权 app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute();//使用mvc路由 }); }
然后我们再运行项目 就会显示一个页面 这样的话就说明成功了! ok 那这一章先到这 下一章会结合api 简单的授权和认证一下!如果看懂了请关注我 第一次写!!!


浙公网安备 33010602011771号