IdentityServer4 系列 【五】-- 授权码模式寮现单点登陆

好久没更新了,前几期使用了密码模式和客户端模式,本期将使用授权码模式实现单身登陆的操作,授权码模式是四个模式中的精髓,理论上的就不说了,大家自行百度,相信也不难,直接上代码。

1、新建服务端的项目具体流程和大部分文件与前几期密码模式相同,只是在Config.cs文件中,定义client时进行了改动。

 return new List<Client> {
            new Client {
                 ClientId="client1",
                    ClientSecrets={new Secret("api1".Sha256())},
                    AllowedGrantTypes=GrantTypes.Code,// 授权码模式
                    RequireConsent=false,
                    RequirePkce=true,

                    RedirectUris={ "http://localhost:4002/signin-oidc","http://localhost:4000/signin-oidc"}, // 各系统的客户端地址,其中signin-oidc是固定的

                    PostLogoutRedirectUris={ "http://localhost:4000/signout-callback-oidc","http://localhost:4002/signout-callback-oidc"},// 各系统的客户端地址,注销时使用
                    
                    AllowedScopes=new List<string>{
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        "api1", // 服务资源
                    }, 
                    // 增加离线授权访问
                    AllowOfflineAccess=true
            }
            };

2、引入模板,这块还需要再研究一下,界面是微软统一的,通用的,呵呵,还得花点时间变成自己想要的。

             先安装模板             

dotnet new -i identityserver4.templates

        将模板安装到项目中

dotnet new is4ui

3、修改startup.cs文件

注意有一块是针对谷歌浏览器的代码,谷歌浏览器跳转问题的,之前貌似也不好用,后来我更新了谷歌浏览器后可以用了,也不知道是不是更新的问题。

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryApiScopes(Config.GetApiScopes())
                .AddInMemoryClients(Config.GetClients())
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddTestUsers(Config.GetTestUsers().ToList());

            services.AddCors(options => {
                options.AddPolicy("any", builder =>
                {
                    builder.WithOrigins("*");
                });
            });

            services.AddControllersWithViews();

            services.Configure<CookiePolicyOptions>(options =>
            {
                options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Lax;
            });//这块是用来针对谷歌浏览器跳转问题的
        }

        // 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.UseCookiePolicy();

            app.UseCors("any");

            app.UseIdentityServer();

            app.UseRouting();

            app.UseStaticFiles();


            app.UseEndpoints(endopint =>
            {
                endopint.MapDefaultControllerRoute();
            });
        }

  

好了,这里服务器端的就完成了,下面是客户端

5、新建客户端项目

用nuget引入一个包 Microsoft.AspNetCore.Authentication.OpenIdConnect,下这个的时候要注意跟.net core的版本对应,我用的是core 3.1,下的是3.16的版本,大家自行引入

startup.cs 文件内容

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddHttpClient();

//这块貌似也是对谷歌浏览器的或者HTTPS的,很奇怪,用IE没问题。用谷歌就有,更新后无此问题。 services.Configure<CookiePolicyOptions>(options => { options.MinimumSameSitePolicy = SameSiteMode.Unspecified; options.OnAppendCookie = cookieContext => SetSameSite(cookieContext.Context, cookieContext.CookieOptions); options.OnDeleteCookie = cookieContext => SetSameSite(cookieContext.Context, cookieContext.CookieOptions); }); services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; }) .AddCookie("Cookies") .AddOpenIdConnect("oidc", options => { options.Authority = "http://localhost:5000"; // 服务端地址 options.RequireHttpsMetadata = false; options.ClientId = "client1"; options.ClientSecret = "api1"; options.ResponseType = "code"; options.SaveTokens = true; options.Scope.Add("offline_access"); options.Scope.Add("openid"); options.Scope.Add("profile"); options.Scope.Add("api1"); }); } public void SetSameSite(HttpContext httpContext, CookieOptions options) { if (options.SameSite == SameSiteMode.None) { if (httpContext.Request.Scheme != "https") { options.SameSite = SameSiteMode.Unspecified; } } } // 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.UseCookiePolicy(); app.UseHttpsRedirection(); app.UseStaticFiles();
app.UseAuthentication(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); }); }

6、新建一个控制器,加上鉴权属性,即可。

using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace IdentityClient.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {
        [HttpGet]
        public IActionResult Index()
        {
            return Content("bbb");
        }
    }
}

  另外,多个客户端时就是startup.cs即可,然后在服务器端把地址加上,这块最好是用数据库模式。不然老改代码可不行,配置文件也可以,这期就到这里。

 

上一篇:windows 可以上网,显示无网络连接


下一篇:6.5 scp:远程文件复制