好久没更新了,前几期使用了密码模式和客户端模式,本期将使用授权码模式实现单身登陆的操作,授权码模式是四个模式中的精髓,理论上的就不说了,大家自行百度,相信也不难,直接上代码。
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即可,然后在服务器端把地址加上,这块最好是用数据库模式。不然老改代码可不行,配置文件也可以,这期就到这里。