今天我們講解的是關於net core 中用IdentityServer4 做單點登錄和注冊登錄。
1,我們需要新建一個net core 的項目,如下圖:
2,我們需要新建一個登錄的控制器,封裝登錄的方法 (首頁視圖登錄和判斷邏輯最好分開),代碼如下:
- [ ]
- public IActionResult Login(string returnUrl = null)
- {
- ViewData["returnUrl"] = returnUrl;
- return View();
- }
- /// <summary>
- /// 登錄post回發處理
- /// </summary>
- [ ]
- public async Task<IActionResult> Login(string userName, string password, string returnUrl = null)
- {
- ViewData["returnUrl"] = returnUrl;
- Customers customers= _userDAL.Login(userName, password);
- //UserDAL userDAL = new UserDAL(); //不予許實例化對象
- if (customers != null)
- {
- AuthenticationProperties props = new AuthenticationProperties
- {
- IsPersistent = true,
- ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromDays(1)),
- };
- //注意這里應該引用Microsoft.AspNetCore.Http這個下面的
- await HttpContext.SignInAsync("10000", userName, props);
- //HttpContext.SignOutAsync();
- if (returnUrl != null)
- {
- return Redirect(returnUrl);
- //return Redirect("http://localhost:44396/home/index");
- }
- return View();
- }
- else
- {
- return Content("登錄失敗");
- }
- }
前台代碼如下:
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>Login</title>
- </head>
- <body>
- <div align="center">
- <h1>.net58統一認證登錄中心</h1>
- <form method="post" action="/Acount/Login">
- 用戶名:<input type="text" name="userName" /><br />
- 密 碼:<input type="password" name="password" />
- <input type="hidden" name="returnUrl" value="@ViewData["returnUrl"]" /> <br />
- <input type="submit" value="登錄" />
- </form>
- </div>
- </body>
- </html>
3,我們需要添加一個類,Config,在里面實現單點登錄的方法,當然也需要依賴注入identityServer4,代碼如下:
- public class Config
- {
- //下載ids4的依賴:install-package IdentityServer4 -version 2.1.1
- // scopes define the resources in your system
- public static IEnumerable<IdentityResource> GetIdentityResources()
- {
- return new List<IdentityResource>
- {
- new IdentityResources.OpenId(),
- new IdentityResources.Profile(),
- };
- }
- // clients want to access resources (aka scopes)
- public static IEnumerable<Client> GetClients()
- {
- return new List<Client>
- {
- // OpenID Connect隱式流客戶端(MVC)
- new Client
- {
- ClientId = "net58.order",
- ClientName = "MVC Client",
- AllowedGrantTypes = GrantTypes.Implicit,//隱式方式
- RequireConsent=false,//如果不需要顯示否同意授權 頁面 這里就設置為false
- RedirectUris = { "http://localhost:60944/signin-oidc", "http://localhost:33447/account/index" },//登錄成功后返回的客戶端地址
- //PostLogoutRedirectUris = { "http://localhost:60944/signout-callback-oidc" },//注銷登錄后返回的客戶端地址
- AllowedScopes =
- {
- IdentityServerConstants.StandardScopes.OpenId,
- IdentityServerConstants.StandardScopes.Profile
- }
- },
- new Client
- {
- ClientId = "net58.product",
- ClientName = "MVC Client",
- AllowedGrantTypes = GrantTypes.Implicit,//隱式方式
- RequireConsent=false,//如果不需要顯示否同意授權 頁面 這里就設置為false
- RedirectUris = { "http://localhost:61739/signin-oidc", "http://localhost:33447/account/index" },//登錄成功后返回的客戶端地址
- //PostLogoutRedirectUris = { "http://localhost:61739/signout-callback-oidc" },//注銷登錄后返回的客戶端地址
- AllowedScopes =
- {
- IdentityServerConstants.StandardScopes.OpenId,
- IdentityServerConstants.StandardScopes.Profile
- }
- }
- };
- }
- }
思路分析:我們可以NuGet包依賴注入ids4,后面的ClientId,ClientName,RedirectUris 就分別配置為其他兩個單點項目的Startup.cs服務里
4,我們需要在登錄項目的Startup.cs服務里配置Ids4服務的相關文件,代碼如下:
- public void ConfigureServices(IServiceCollection services)
- {
- //好像是歐盟聯盟協議的cookie,要注釋
- //services.Configure<CookiePolicyOptions>(options =>
- //{
- // // This lambda determines whether user consent for non-essential cookies is needed for a given request.
- // options.CheckConsentNeeded = context => true;
- // options.MinimumSameSitePolicy = SameSiteMode.None;
- //});
- services.AddIdentityServer()//Ids4服務
- .AddDeveloperSigningCredential()//添加開發人員簽名憑據
- .AddInMemoryIdentityResources(Config.GetIdentityResources()) //添加內存apiresource
- .AddInMemoryClients(Config.GetClients());//把配置文件的Client配置資源放到內存
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
- }
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IHostingEnvironment env)
- {
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- else
- {
- app.UseExceptionHandler("/Home/Error");
- }
- app.UseStaticFiles();
- app.UseCookiePolicy();
- //啟動ids4中間件
- app.UseIdentityServer();
- app.UseMvc(routes =>
- {
- routes.MapRoute(
- name: "default",
- template: "{controller=Home}/{action=Index}/{id?}");
- });
- }
tip:初學者可以參考里面的配置,沒有的要加上哦。
5,項目就需要在子項目進行配置了 (這里做功能測試,所以只建了兩個子項目,大型項目的話可以弄多個進行單點登錄的)
這里,我們新建商品和價格,兩個子項目來進行單點登錄。
- //下載ids4的依賴:install-package IdentityServer4 -version 2.1.1
Startup.cs服務里配置代碼如下圖:
- app.UseStaticFiles();
- app.UseCookiePolicy();
- //身份驗證 批准; 授權
- app.UseAuthentication();
- //啟動session 中間件
- app.UseSession();
- app.UseMvc(routes =>
- {
- routes.MapRoute(
- name: "default",
- template: "{controller=Home}/{action=Index}/{id?}");
- });
在新建的控制器,只需要一個特寫權限,視圖的話就寫上登錄成功訪問就行了。
這個價格子項目配置好了之后,另外那個商品子項目的配置也一致。
下面我們就可以運行子項目,開始你訪問該控制器(UserCenter)下的index視圖,他會跳轉到登錄項目進行登錄
登錄成功后就返回到當前的價格子項目,然后我們再運行商品子項目,會發現他就不需要登錄就可以訪問index視圖下的登錄成功訪問的話語。
tip:運行時,我們可以清楚看到登錄界面和登錄成功后的頁面的路由路徑是不一致的,所以就實現了單點登錄的效果。
第二項內容就是:實現注銷登錄:(隨便一個子項目退出登錄,其他項目也就退出了登錄)
1,在以上的基礎上,還是在登錄控制器封裝注銷登錄的方法,代碼如下:
- public class AccountController : Controller
- {
- //依賴注入:做注銷登錄
- private readonly IIdentityServerInteractionService _interaction;
- public AccountController(IIdentityServerInteractionService interaction)
- {
- _interaction = interaction;
- }
- //注銷登錄
- [ ]
- public async Task<IActionResult> Logout(string logoutId)
- {
- var logout = await _interaction.GetLogoutContextAsync(logoutId);
- await HttpContext.SignOutAsync();
- //if (logout.PostLogoutRedirectUri != null)
- //{
- // return Redirect(logout.PostLogoutRedirectUri);
- //}
- //獲取客戶端點擊注銷登錄的地址
- var refererUrl = Request.Headers["Referer"].ToString();
- if (!string.IsNullOrWhiteSpace(refererUrl))
- {
- return Redirect(refererUrl);
- }
- else
- {
- //獲取配置的默認的注銷登錄后的跳轉地址
- if (logout.PostLogoutRedirectUri != null)
- {
- return Redirect(logout.PostLogoutRedirectUri);
- }
- }
- return View();
- }
2,在價格子項目為例:在UserCenter控制器加一個視圖類:
- //退出登錄
- public IActionResult LoginOut()
- {
- return SignOut("Cookies", "oidc");
- }
3,最后一步,我們就在子項目隨便一個控制器運行,然后寫連接跳轉到退出登錄的控制器下的類訪問就可以實現退出,他就會返回該子項目
且處於未登錄狀態,我們以另外一個商品項目啟動運行,訪問那個提示登錄成功訪問的視圖,發現需要重新登錄。
效果完成后就達到單點注銷登錄啦。不容易呀,知識還是需要慢慢啃哦,加油。
隨筆轉自:https://www.tnblog.net/15985459135/article/details/3055