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"
      }
    }
  }
}
View Code

第一步:添加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,
                    },
                   
                },
            };
        }
    }
View Code

填坑:这里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());//添加系统中的资源
        }
View Code

Configure方法中添加如下代码 必须在app.UseRouting();与 app.UseEndpoints方法之间调用,否则失效无用

  app.UseIdentityServer();//使用identity server中间件
            app.UseAuthentication();//使用授权
View Code

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路由
            });
        }
View Code

然后我们再运行项目 就会显示一个页面   这样的话就说明成功了! ok 那这一章先到这 下一章会结合api 简单的授权和认证一下!如果看懂了请关注我 第一次写!!!

posted @ 2020-09-15 14:53  努力变成大佬  阅读(439)  评论(0)    收藏  举报