.net core 使用ids4进行单点登录和注销登录

IdentityServer4是为ASP.NET CORE量身定制的实现了OpenId Connect和OAuth2.0协议的认证授权中间件。

脑图网站:https://naotu.baidu.com/file/75b251257ce27cfa62e0ad7f47b75576?token=e2db617be22b6274

  今天我们讲解的是关于net core 中用IdentityServer4 做单点登录和注册登录。

    1,我们需要新建一个net core 的项目,如下图:

    

 

    

 

  2,我们需要新建一个登录的控制器,封装登录的方法 (首页视图登录和判断逻辑最好分开),代码如下:

     

  1.      [HttpGet]
  2.       public IActionResult Login(string returnUrl = null)
  3.         {
  4.             ViewData["returnUrl"] = returnUrl;
  5.             return View();
  6.         }
  7.         /// <summary>
  8.         /// 登录post回发处理
  9.         /// </summary>
  10.         [HttpPost]
  11.         public async Task<IActionResult> Login(string userName, string password, string returnUrl = null)
  12.         {
  13.             ViewData["returnUrl"] = returnUrl;
  14.               Customers customers= _userDAL.Login(userName, password);
  15.             //UserDAL userDAL = new UserDAL();  //不予许实例化对象
  16.             if (customers != null)
  17.             {
  18.                 AuthenticationProperties props = new AuthenticationProperties
  19.                 {
  20.                     IsPersistent = true,
  21.                     ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromDays(1)),
  22.                 };
  23.                 //注意这里应该引用Microsoft.AspNetCore.Http这个下面的
  24.                 await HttpContext.SignInAsync("10000", userName, props);
  25.                 //HttpContext.SignOutAsync();
  26.                 if (returnUrl != null)
  27.                 {
  28.                     return Redirect(returnUrl);
  29.                     //return Redirect("http://localhost:44396/home/index");
  30.                 }
  31.                 return View();
  32.             }
  33.             else
  34.             {
  35.                 return Content("登录失败");
  36.             }
  37.         }

    前台代码如下:

  1. <html>
  2. <head>
  3.     <meta name="viewport" content="width=device-width" />
  4.     <title>Login</title>
  5. </head>
  6. <body>
  7.     <div align="center">
  8.         <h1>.net58统一认证登录中心</h1>
  9.         <form method="post" action="/Acount/Login">
  10.             用户名:<input type="text" name="userName" /><br />
  11.             密  码:<input type="password" name="password" />
  12.             <input type="hidden" name="returnUrl" value="@ViewData["returnUrl"]" /> <br />
  13.             <input type="submit" value="登录" />
  14.         </form>
  15.     </div>
  16. </body>
  17. </html>

3,我们需要添加一个类,Config,在里面实现单点登录的方法,当然也需要依赖注入identityServer4,代码如下:

      

  1.  public class Config
  2.     {
  3.         //下载ids4的依赖:install-package IdentityServer4  -version 2.1.1
  4.         // scopes define the resources in your system
  5.         public static IEnumerable<IdentityResource> GetIdentityResources()
  6.         {
  7.             return new List<IdentityResource>
  8.             {
  9.                 new IdentityResources.OpenId(),
  10.                 new IdentityResources.Profile(),
  11.             };
  12.         }
  13.         // clients want to access resources (aka scopes)
  14.         public static IEnumerable<Client> GetClients()
  15.         {
  16.             return new List<Client>
  17.             {
  18.                 // OpenID Connect隐式流客户端(MVC)
  19.                 new Client
  20.                 {
  21.                     ClientId = "net58.order",
  22.                     ClientName = "MVC Client",
  23.                     AllowedGrantTypes = GrantTypes.Implicit,//隐式方式
  24.                     RequireConsent=false,//如果不需要显示否同意授权 页面 这里就设置为false                      
  25.                     RedirectUris = { "http://localhost:60944/signin-oidc", "http://localhost:33447/account/index" },//登录成功后返回的客户端地址
  26.                     //PostLogoutRedirectUris = { "http://localhost:60944/signout-callback-oidc" },//注销登录后返回的客户端地址
  27.                     AllowedScopes =
  28.                     {
  29.                         IdentityServerConstants.StandardScopes.OpenId,
  30.                         IdentityServerConstants.StandardScopes.Profile
  31.                     }
  32.                 },
  33.                  new Client
  34.                 {
  35.                     ClientId = "net58.product",
  36.                     ClientName = "MVC Client",
  37.                     AllowedGrantTypes = GrantTypes.Implicit,//隐式方式
  38.                     RequireConsent=false,//如果不需要显示否同意授权 页面 这里就设置为false                      
  39.                     RedirectUris = { "http://localhost:61739/signin-oidc", "http://localhost:33447/account/index" },//登录成功后返回的客户端地址
  40.                     //PostLogoutRedirectUris = { "http://localhost:61739/signout-callback-oidc" },//注销登录后返回的客户端地址
  41.                     AllowedScopes =
  42.                     {
  43.                         IdentityServerConstants.StandardScopes.OpenId,
  44.                         IdentityServerConstants.StandardScopes.Profile
  45.                     }
  46.                 }
  47.             };
  48.         }
  49.     }

思路分析:我们可以NuGet包依赖注入ids4,后面的ClientId,ClientName,RedirectUris 就分别配置为其他两个单点项目的Startup.cs服务里

  4,我们需要在登录项目的Startup.cs服务里配置Ids4服务的相关文件,代码如下:

  1.  public void ConfigureServices(IServiceCollection services)
  2.         {
  3.             //好像是欧盟联盟协议的cookie,要注释
  4.             //services.Configure<CookiePolicyOptions>(options =>
  5.             //{
  6.             //    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
  7.             //    options.CheckConsentNeeded = context => true;
  8.             //    options.MinimumSameSitePolicy = SameSiteMode.None;
  9.             //});
  10.             services.AddIdentityServer()//Ids4服务
  11.              .AddDeveloperSigningCredential()//添加开发人员签名凭据
  12.              .AddInMemoryIdentityResources(Config.GetIdentityResources()) //添加内存apiresource
  13.              .AddInMemoryClients(Config.GetClients());//把配置文件的Client配置资源放到内存
  14.            
  15.             services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  16.         }
  17.         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  18.         public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  19.         {
  20.             if (env.IsDevelopment())
  21.             {
  22.                 app.UseDeveloperExceptionPage();
  23.             }
  24.             else
  25.             {
  26.                 app.UseExceptionHandler("/Home/Error");
  27.             }
  28.             app.UseStaticFiles();
  29.             app.UseCookiePolicy();
  30.             //启动ids4中间件
  31.             app.UseIdentityServer();
  32.             app.UseMvc(routes =>
  33.             {
  34.                 routes.MapRoute(
  35.                     name: "default",
  36.                     template: "{controller=Home}/{action=Index}/{id?}");
  37.             });
  38.         }

  tip:初学者可以参考里面的配置,没有的要加上哦。

 5,项目就需要在子项目进行配置了 (这里做功能测试,所以只建了两个子项目,大型项目的话可以弄多个进行单点登录的)

 这里,我们新建商品和价格,两个子项目来进行单点登录。

  1.  //下载ids4的依赖:install-package IdentityServer4  -version 2.1.1

 

Startup.cs服务里配置代码如下图:

  

  

       

  1.    app.UseStaticFiles();
  2.             app.UseCookiePolicy();
  3.             //身份验证  批准; 授权
  4.             app.UseAuthentication();
  5.             //启动session 中间件
  6.             app.UseSession();
  7.             app.UseMvc(routes =>
  8.             {
  9.                 routes.MapRoute(
  10.                     name: "default",
  11.                     template: "{controller=Home}/{action=Index}/{id?}");
  12.             });

  在新建的控制器,只需要一个特写权限,视图的话就写上登录成功访问就行了。

  

 

这个价格子项目配置好了之后,另外那个商品子项目的配置也一致。

下面我们就可以运行子项目,开始你访问该控制器(UserCenter)下的index视图,他会跳转到登录项目进行登录

  登录成功后就返回到当前的价格子项目,然后我们再运行商品子项目,会发现他就不需要登录就可以访问index视图下的登录成功访问的话语。

 

tip:运行时,我们可以清楚看到登录界面和登录成功后的页面的路由路径是不一致的,所以就实现了单点登录的效果。

 

 第二项内容就是:实现注销登录:(随便一个子项目退出登录,其他项目也就退出了登录)

 1,在以上的基础上,还是在登录控制器封装注销登录的方法,代码如下:

   

  1. public class AccountController : Controller
  2.     {
  3. //依赖注入:做注销登录
  4.         private readonly IIdentityServerInteractionService _interaction;
  5.         public AccountController(IIdentityServerInteractionService interaction)
  6.         {
  7.             _interaction = interaction;
  8.           
  9.         }
  10.         //注销登录
  11.         [HttpGet]
  12.         public async Task<IActionResult> Logout(string logoutId)
  13.         {
  14.             var logout = await _interaction.GetLogoutContextAsync(logoutId);
  15.             await HttpContext.SignOutAsync();
  16.             //if (logout.PostLogoutRedirectUri != null)
  17.             //{
  18.             //    return Redirect(logout.PostLogoutRedirectUri); 
  19.             //}
  20.             //获取客户端点击注销登录的地址
  21.             var refererUrl = Request.Headers["Referer"].ToString();
  22.             if (!string.IsNullOrWhiteSpace(refererUrl))
  23.             {
  24.                 return Redirect(refererUrl);
  25.             }
  26.             else
  27.             {
  28.                 //获取配置的默认的注销登录后的跳转地址
  29.                 if (logout.PostLogoutRedirectUri != null)
  30.                 {
  31.                     return Redirect(logout.PostLogoutRedirectUri);
  32.                 }
  33.             }
  34.             return View();
  35.         }

2,在价格子项目为例:在UserCenter控制器加一个视图类:

   

  1. //退出登录
  2. public IActionResult LoginOut()
  3.         {
  4.             return SignOut("Cookies", "oidc");
  5.         }

3,最后一步,我们就在子项目随便一个控制器运行,然后写连接跳转到退出登录的控制器下的类访问就可以实现退出,他就会返回该子项目

    且处于未登录状态,我们以另外一个商品项目启动运行,访问那个提示登录成功访问的视图,发现需要重新登录。

    效果完成后就达到单点注销登录啦。不容易呀,知识还是需要慢慢啃哦,加油。

posted @ 2021-03-26 13:27  dreamw  阅读(2160)  评论(0编辑  收藏  举报