• IdentityServer4 实现单点登录


    服务端

        public class Config
        {
    
            /// <summary>
            /// IDS资源
            /// </summary>
            /// <returns></returns>
            public static IEnumerable<IdentityResource> GetIds()
            {
                return new List<IdentityResource>
                {
                    new IdentityResources.OpenId(),
                    new IdentityResources.Profile(),
                };
            }
    
            public static IEnumerable<ApiResource> GetApiResources()
            {
                return new List<ApiResource>
                {
                    new ApiResource("UserCenter", "UserCenter API")
                };
            }
    
            public static IEnumerable<ApiScope> GetApiScopes()
            {
                return new List<ApiScope>
                {
                    new ApiScope("UserCenter", "UserCenter API")
                };
            }
    
            /// <summary>
            /// 可以使用ID4 Server 客户端资源
            /// </summary>
            /// <returns></returns>
            public static IEnumerable<Client> GetClients()
            {
                List<Client> clients = new List<Client>() {
                    ////授权码模式
                    //new Client
                    //{
                    //    ClientId = "client1",
                    //    ClientSecrets = { new Secret("123456".Sha256()) },
                    //    //授权码模式
                    //    AllowedGrantTypes = GrantTypes.Code,
                    //    //需要确认授权
                    //    RequireConsent = true,
                    //    RequirePkce = true,
                    //    //允许token通过浏览器
                    //    AllowAccessTokensViaBrowser=true,               
                    //    // where to redirect to after login(登录)
                    //    RedirectUris = { "https://localhost:7072/signin-oidc" },
                    //    // where to redirect to after logout(退出)
                    //    PostLogoutRedirectUris = { "https://localhost:7072/signout-callback-oidc" },
                    //    //允许的范围
                    //    AllowedScopes = new List<string>
                    //    {
                    //        IdentityServerConstants.StandardScopes.OpenId,
                    //        IdentityServerConstants.StandardScopes.Profile,
                    //        "UserCenter"
                    //    },
                    //    AlwaysIncludeUserClaimsInIdToken=true
                    //},
                    new Client
                    {
                        ClientId = "client2",
                        ClientSecrets = { new Secret("123456".Sha256()) },
                        //混合与客户端模式
                        AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                        //需要确认授权
                        RequireConsent = true,
                        RequirePkce = false,
                        //允许token通过浏览器
                        AllowAccessTokensViaBrowser=true,               
                        // where to redirect to after login(登录)
                        RedirectUris = { "https://localhost:7072/signin-oidc" },
                        // where to redirect to after logout(退出)
                        PostLogoutRedirectUris = { "https://localhost:7072/signout-callback-oidc" },
                        AccessTokenLifetime = 3600,//Token 过期时间
                        //AccessTokenType= AccessTokenType.Jwt,
                        AlwaysIncludeUserClaimsInIdToken = true,//将用户所有的claims包含在IdToken内
                        //AbsoluteRefreshTokenLifetime = 2592000,//RefreshToken的最长生命周期,默认30天
                        //RefreshTokenExpiration = TokenExpiration.Sliding,//刷新令牌时,将刷新RefreshToken的生命周期。RefreshToken的总生命周期不会超过AbsoluteRefreshTokenLifetime。
                        //SlidingRefreshTokenLifetime = 3600,//以秒为单位滑动刷新令牌的生命周期。
                        AllowOfflineAccess = true,//如果要获取refresh_tokens ,必须把AllowOfflineAccess设置为true  
                        //允许的范围
                        AllowedScopes = new List<string>
                        {
                            //"UserCenter",
                            IdentityServerConstants.StandardScopes.OpenId,
                            IdentityServerConstants.StandardScopes.Profile
                            
                        },
                    }
                };
                return clients;
            }
    
            /// <summary>
            /// 定义可以使用ID4的用户资源
            /// </summary>
            /// <returns></returns>
            public static List<TestUser> GetUsers()
            {
                return new List<TestUser>()
                {
                    new TestUser
                    {
                            SubjectId = "001",
                            Username = "ypf1",    //账号
                            Password = "1",  //密码
                            Claims =
                            {
                                new Claim(JwtClaimTypes.Name, "Alice Smith"),
                                new Claim(JwtClaimTypes.Email, "AliceSmith@email.com"),
                            }
                     },
                     new TestUser
                     {
                            SubjectId = "002",
                            Username = "ypf2",
                            Password = "1",
                            Claims =
                            {
                                new Claim(JwtClaimTypes.Name, "Bob Smith"),
                                new Claim(JwtClaimTypes.Email, "BobSmith@email.com"),
                            }
                      }
                };
            }
        }
    

      Startup 代码

            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllersWithViews();
    
                //注册IDS4信息(授权码模式)
                services.AddIdentityServer(options=> {
                    options.Authentication.CookieAuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme;            
                })
                .AddDeveloperSigningCredential()
                .AddInMemoryIdentityResources(Config.GetIds())
                .AddInMemoryClients(Config.GetClients())
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryApiScopes(Config.GetApiScopes())
                .AddTestUsers(Config.GetUsers());
    
                services
                    .AddAuthentication(options=> {
    //默认为Cookie 同时支持Jwt options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => { // IdentityServer4 地址 options.Authority = "http://localhost:7071"; options.RequireHttpsMetadata = false; options.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = false,//是否验证Issuer ValidateAudience = false,//是否验证Audience ValidateLifetime = true,//是否验证失效时间 ValidateIssuerSigningKey = false,//是否验证SecurityKey //ValidAudience = "UserCenter",//Audience //ValidIssuer = "yourdomain.com",//Issuer,这两项和前面签发jwt的设置一致 //ValidAudiences = new List<string>() { "client2" }//, "api1" }; }); } // 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"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); //启用IDS4 app.UseIdentityServer(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }

     api 使用jwt验证

        [Route("api/[controller]/[action]")]
        [ApiController]
        [Authorize(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)]//(JwtBearerDefaults.AuthenticationScheme)
        public class DemoController : ControllerBase
        {
            [Authorize]
            public JsonResult Index()
            {
                //string str = OpenIdConnectParameterNames.RefreshToken;
    
                string accessToken = HttpContext.GetTokenAsync("access_token").Result;
                string idToken = HttpContext.GetTokenAsync("id_token").Result;
                var refreshToken = HttpContext.GetTokenAsync("refresh_token").Result;
    
                var claimsList = from c in User.Claims select new { c.Type, c.Value };
    
    
                return new JsonResult(new
                {
                    data = new
                    {
                        accessToken,
                        idToken,
                        refreshToken,
                        claimsList
                    }
                });
            }
        }
    

     同时服务端需要下载IdentityServer4.Quickstart.UI 代码 (github上有)

    以下3个文件复制到你的服务端项目中

    客户端

    Startup代码

        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();
    
                JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
                JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
                //添加Cookie认证
                services.AddAuthentication(options =>
                {
                    options.DefaultScheme = "Cookies";
                    options.DefaultChallengeScheme = "oidc";
                })
                .AddCookie("Cookies")
                //通过OIDC协议远程请求认证
                .AddOpenIdConnect("oidc", options =>
                {
                    options.Authority = "http://localhost:7071";   //认证授权服务器地址
    
                    #region 授权码模式
                    //options.RequireHttpsMetadata = false;
                    //options.ClientId = "client1";    //客户端ID
                    //options.ClientSecret = "123456"; //客户端秘钥
                    ////授权码模式
                    //options.ResponseType = OpenIdConnectResponseType.Code;
                    //options.ResponseMode = OpenIdConnectResponseMode.Query;
                    //options.SaveTokens = true; 
                    #endregion
    
                    #region 混合客户端模式
                    options.RequireHttpsMetadata = false;
                    options.ClientId = "client2";    //客户端ID
                    options.ClientSecret = "123456"; //客户端秘钥
                    //混合客户端模式
                    options.ResponseType = OpenIdConnectResponseType.CodeIdTokenToken;
                    //options.ResponseMode = OpenIdConnectResponseMode.Query;
                    options.SaveTokens = true;
                    #endregion
                });
            }
    
            // 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");
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
                app.UseHttpsRedirection();
                app.UseStaticFiles();
    
                app.UseRouting();
    
                //开启认证
                app.UseAuthentication();
                //开启授权
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller=Home}/{action=Index}/{id?}");
                });
            }
        }
    

      客户端api增加授权控制,在没有授权的情况下访问,客户端会跳转到服务端登录进行认证,认证通过会转回到客户端

    这里服务端认证中心可以提供获取用户信息接口,客户端可以使用拿到的token请求认证中心的用户信息接口

  • 相关阅读:
    SERU最佳需求分析方法
    需求规格说明书(Volere版)
    开发设计模式之设计六大原则
    清晰、高效、一致、美观 – 关于设计原则的优先级排序
    一个案例,三个角色,简单说下B端产品的权限设计
    如何从0到1打造一个完美的业务系统?
    MarkdownPad2.5 注册码
    WEBSTORM快捷键
    jQuery
    BOM与DOM
  • 原文地址:https://www.cnblogs.com/zxcnn/p/14241525.html
Copyright © 2020-2023  润新知