什么是单点登录统一认证:假如某公司旗下有10个网站(比如各种管理网站:人事系统啊,财务系统啊,业绩系统啊等),我是该公司一管理员或者用户,按照传统网站模式是这样:我打开A网站 输入账号密码 然后进入到A网站办点事,办完之后,我有需要到B网站去办点事,这个时候又需要输入账号密码,假如你还要到C网站办点事,又再需要输入账号密码。。。。。

  为了解决这个问题,所以出现了单点登录统一认证:即 该改管理员 登录了其中一个网站得到了ids4的授权之后,他再登入该公司旗下其他网站的时候不需要在输入账号密码,能够直接进入后台办事! 这就是单点登录统一认证!

本文章目的:

使用IdentityServer4做一个单点登录统一认证的例子。我会用最简洁的代码和最能让新手懂的方式,来完成这个例子,不会像官方例子一样让新手看起来很吃力,因为我自己就体验过那种感觉^_^

1.用户访问一个MVC网站 A,A网站发现用户没有登录授权,然后跳转到ids4服务去登录

2.如果用户在ids4的登录页面上输入了正确的账号密码(从数据库某个用户表验证),则跳转回A网站,然后A网站就可以显示相关的内容

前言:

  博主为了研究ids4,把官方文档断断续续看了几遍,还有网上的很多大神文章都看了下,一句话,看的很累!一直没有找到这么纯粹又实用的例子,经过千难万苦的研究,终于有点成果,现在我决心把这些东西试着以最简单的方式写出来给大家参考,即使你是菜鸟跟着我的步骤来 你也能做出来!大神就忽略哈,如有指教或者建议,请留言!

有兴趣爱好一起学习交流netcore相关技术的加群:275080612

开发环境:

vs2017 、net Core 2.1、sqlserver2012

一。搭建IdentityServer4服务端

打开VS2017,新建 netcore项目:    名字叫:IdentityS4, 然后选择webMVC这个,如下图:

引进安装依赖项:IdentityServer4

设置该项目的地址为:http://localhost:5000

新建一个配置文件类:Config.cs  代码如下:

public class Config{// scopes define the resources in your systempublic static IEnumerable<IdentityResource> GetIdentityResources(){return new List<IdentityResource>{new IdentityResources.OpenId(),new IdentityResources.Profile(),};}
    // clients want to access resources (aka scopes)public static IEnumerable&lt;Client&gt; GetClients(){return new List&lt;Client&gt;{// OpenID Connect隐式流客户端(MVC)new Client{ClientId = "mvc",ClientName = "MVC Client",AllowedGrantTypes = GrantTypes.Implicit,//隐式方式RequireConsent=false,//如果不需要显示否同意授权 页面 这里就设置为falseRedirectUris = { "http://localhost:5002/signin-oidc" },//登录成功后返回的客户端地址PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },//注销登录后返回的客户端地址AllowedScopes =//下面这两个必须要加吧 不太明白啥意思{IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile}}};}
}</pre>

在Startup.cs的ConfigureServices方法中注入Ids4服务,如下面红色部分代码:

public void ConfigureServices(IServiceCollection services){services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddIdentityServer()//Ids4服务.AddDeveloperSigningCredential().AddInMemoryIdentityResources(Config.GetIdentityResources()).AddInMemoryClients(Config.GetClients());//把配置文件的Client配置资源放到内存}</pre>

在Startup.cs的Configure方法中添加ids4服务中间件(注意要放在UseMvc之前就可以):

app.UseIdentityServer();

现在ids4本身的基本的配置弄好了,下面我们要开始弄跟数据库相关的东西了,大家想想,既然要登录,那肯定需要连接数据库并且读取出其中的用户信息去验证,比如账号、密码。好的,那我们就按照下面一步一步来做

添加DbContext类 名字叫:EFContext.cs ,代码如下(其中红色部分是我们待会需要添加的实体类,也就是对应数据库里面的用户表Admin):

public class EFContext : DbContext{public EFContext(DbContextOptions<EFContext> options) : base(options){
    }#region 实体集public DbSet&lt;Admin&gt; Admin { get; set; }//注意 这里这个Admin不能写成Admins否则会报错找不到Admins 因为我们现在数据库和表是现成的 这里就相当于实体对应的数据库是Admin#endregion
}</pre>

添加一个Admin.cs的实体类,对应数据库里面的用户表Admin (然后把这个实体类添加到上一步的EFContext中,也就是上一步代码的红色部分)

public class Admin{public int Id { get; set; }public DateTime CreateDate { get; set; }public string UserName { get; set; }public string Password { get; set; }public string Remark { get; set; }}

在Startup.cs的ConfigureServices方法中注入 EFContext,如下面红色部分代码:

public void ConfigureServices(IServiceCollection services){services.AddDbContext<EFContext>(options=>options.UseSqlServer(Configuration.GetConnectionString("conn")));//注入DbContext
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);services.AddIdentityServer()//Ids4服务.AddDeveloperSigningCredential().AddInMemoryIdentityResources(Config.GetIdentityResources()).AddInMemoryClients(Config.GetClients());//把配置文件的Client配置资源放到内存}</pre>

接下来,我们就要写Admin这个实体类跟数据库打交道的代码了,比如增删改查啊,在net中一般交DAL层,在netCore中 一般交services层,要注意的是 netcore的框架是IOC的框架,依赖注入的,所以这个services层需要接口的形式!

新建一个接口:IAdminService.cs 代码如下:

public interface IAdminService{Task<Admin> GetByStr(string username, string pwd);//根据用户名和密码查找用户}

新建实现该接口的类AdminService.cs

public class AdminService:IAdminService{public EFContext db;public AdminService(EFContext _efContext){db = _efContext;}/// <summary>/// 验证用户,成功则返回用户信息,否则返回null/// </summary>/// <param name="username"></param>/// <param name="pwd"></param>/// <returns></returns>public async Task<Admin> GetByStr(string username, string pwd){Admin m=await db.Admin.Where(a => a.UserName == username && a.Password == pwd).SingleOrDefaultAsync();if (m!=null){return m;}else{return null;}}}    

在Startup.cs的ConfigureServices方法中注入 service层,如下面红色部分代码:

public void ConfigureServices(IServiceCollection services){services.AddDbContext<EFContext>(options=>options.UseSqlServer(Configuration.GetConnectionString("conn")));//注入DbContextservices.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddIdentityServer()//Ids4服务.AddDeveloperSigningCredential().AddInMemoryIdentityResources(Config.GetIdentityResources()).AddInMemoryClients(Config.GetClients());//把配置文件的Client配置资源放到内存services.AddTransient&lt;IAdminService,AdminService&gt;();//service注入}</pre>

在配置文件appsettings.json中添加数据库连接字符串如下红色部分代码:

{"ConnectionStrings": { "conn": "server=.;database=blogcore;uid=sa;pwd=123" }, "Logging": {"LogLevel": {"Default": "Warning"}},"AllowedHosts": "*"
}

至此,应该是可以正确的连接数据库的,大家可以去Home控制器中查询点数据测试下显示到首页,保证能连接数据库成功的查询出数据就可以。

接下来 我们来做登录页面

新增一个控制器AccountController,代码如下:

public class AccountController : Controller{private IAdminService _adminService;//自己写的操作数据库Admin表的serviceprivate readonly IIdentityServerInteractionService _interaction;private readonly IClientStore _clientStore;private readonly IAuthenticationSchemeProvider _schemeProvider;private readonly IEventService _events;public AccountController(IIdentityServerInteractionService interaction,IClientStore clientStore,IAuthenticationSchemeProvider schemeProvider,IEventService events,IAdminService adminService){_interaction = interaction;_clientStore = clientStore;_schemeProvider = schemeProvider;_events = events;_adminService = adminService;}
    /// &lt;summary&gt;/// 登录页面/// &lt;/summary&gt;[HttpGet]public async Task&lt;IActionResult&gt; Login(string returnUrl=null){ViewData["returnUrl"] = returnUrl;return View();}/// &lt;summary&gt;/// 登录post回发处理/// &lt;/summary&gt;[HttpPost]public async Task&lt;IActionResult&gt; Login(string userName, string password,string returnUrl=null){ViewData["returnUrl"] = returnUrl;Admin user = await _adminService.GetByStr(userName, password);if (user!=null){AuthenticationProperties props= new AuthenticationProperties{IsPersistent = true,ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromDays(1))};await HttpContext.SignInAsync(user.Id.ToString(), user.UserName, props);if (returnUrl!=null){return Redirect(returnUrl);}return View();}else{return View();}}
}</pre>

添加登录view视图,代码如下:

@{Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name=“viewport” content=“width=device-width” />
<title>Login</title>
</head>
<body>

&lt;div align="center"&gt;&lt;h1&gt;统一认证登录中心&lt;/h1&gt;&lt;form action="/Account/Login" method="post"&gt;用户名:&lt;input type="text" name="userName" /&gt;&lt;br /&gt;密 码:&lt;input type="password" name="password" /&gt;&lt;input type="hidden" name="returnUrl" value="@ViewData["returnUrl"]" /&gt; &lt;br /&gt;&lt;input type="submit" value="登录" /&gt;&lt;/form&gt;
&lt;/div&gt;

</body>
</html>

至此,IdentityServer4服务端的工作完成,接下来我们要开始建客户端了,也就是需要保护的MVC网站

二。搭建客户端

新建一个名为 MvcClient 的 

把地址设置为:http://localhost:5002

在Startup.cs的ConfigureServices方法中添加如下红色部分代码(主要用来配置认证中心ids4的及自己作为客户端的认证信息):

public void ConfigureServices(IServiceCollection services){JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        services.AddAuthentication(options =&gt;{options.DefaultScheme = "Cookies";options.DefaultChallengeScheme = "oidc";}).AddCookie("Cookies").AddOpenIdConnect("oidc", options =&gt;{options.SignInScheme = "Cookies";options.Authority = "http://localhost:5000";options.RequireHttpsMetadata = false;options.ClientId = "mvc";options.SaveTokens = true;});services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}</pre>

在 Configure方法中添加这行代码(需要在UseMvc之前就可以):

app.UseAuthentication();

到此,客户端跟统一认证的信息就配置完了。接下来我们把Home控制器上面加上需要验证的标志:[Authorize]

我们把默认的Index视图页面html代码去掉,改成如下(主要用来显示下授权后拿到的用户信息):

@{ViewData["Title"] = "Home Page";
}

<div align=“center”><h1>这里是受保护的客户端首页</h1></div>
<h3>User claims</h3>

<dl>
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>

}

</dl>

到此,客户端的工作也做完了,下面我们要开始启动项目了

设置项目为多项目启动:解决方案上右键-属性

现在我们启动项目:服务器项目和 客户端都运行了,但是客户端会直接跳转到服务端登录页面

服务端

客户端(5002)跳转过来的登录页面:

然后输入正确账号密码 点击登录认证通过之后就跳转回 客户端网站去了

至此 ,例子结束!

从这个例子中,咱们可以再加几个客户端网站,然后统一到这个ids4认证,这样就达到了单点登录统一认证的效果了!

源码下载:https://pan.baidu.com/s/1HRiAF7LMinCh03AZNArfcQ

IdentityServer4实现单点登录统一认证相关推荐

  1. 华为外部Portal认证 Radius认证计费 实现基于Mac快速认证的Mac无感知认证和结合CAS单点登录统一认证平台和AD域LDAP对接配置

    华为外部Portal认证 Radius认证计费 实现基于Mac快速认证的Mac无感知认证 结合CAS单点登录统一认证平台 AD域LDAP对接配置 实现用户名密码实名认证 访客短信认证 二维码扫码 钉钉 ...

  2. [原创]django+ldap+memcache实现单点登录+统一认证

    前言 由于公司内部的系统越来越多,为了方便用户使用,通过django进行了单点登录和统一认证的尝试,目前实现了django项目的单点登录和非django项目的统一认证,中间波折挺多,涉及的技术包括dj ...

  3. java单点登录统一认证,JEECG 集成KiSSO单点登录实现统一身份认证

    JEECG 集成KiSSO单点登录实现统一身份认证 JEECG 如何为其他第三方系统实现统一身份认证服务,实现单点登录? 第三方系统如何对接呢? 今天为大家揭开这层面纱,让大家了解实质,使用它更快速的 ...

  4. Spring+ Spring cloud + SSO单点登录应用认证

    之前的文章中有介绍spring cloud sso集成的方案,也做过spring + jwt + redis的解决方案,不同系统的无缝隙集成,统一的sso单点登录界面的管理.每个应用集成的权限认证,白 ...

  5. SpringSecurity整合Redis实现单点登录及认证返回json数据

    前一阵刚研究了shiro框架,现在再来研究一下SpringSecurity. SpringSecurity是由spring团队开发的,为web应用安全性提供了完整的解决方案的框架.虽然现在使用spri ...

  6. jasig CAS实现单点登录(数据库认证)

    之前转载了一篇IBM的CAS单点登录实现,不过瘾,于是到官网弄下最新版本来再战一把: 这个CAS(Central Authentication Service)是耶鲁大学的开源项目,旨在实现企业应用单 ...

  7. 单点登录SSO(single sign on)模式(单点登录+权限认证)

    一.单点登录三种常见方法: 第一种: session广播机制实现(已过时) session赋值 = 把登录的session对象,复制给其他模块 缺点:如果模块多的话,session复制会造成资源浪费, ...

  8. 单点登录 统一用户管理

    单点登录(Single Sign- On,简称 SSO)是指用户成功登录某个业务系统之后,就可以以一定的权限直接访问其他受信任的业务系统,无需再输入用户名和密码等认证信息,大大方便了用户使用各类业务系 ...

  9. 基于IdentityServer4的单点登录——项目基本结构与流程

    组成 IdentityServer,Api和Client(客户端,asp .net core) 本文以官方demo:https://github.com/IdentityServer/Identity ...

最新文章

  1. php base64尺寸,php实现base64编码
  2. 2014 WAP校园招聘笔试题
  3. java中通过JNA调用dll
  4. mysql带账号联查表_MySQL联表查询的简单示例
  5. Java解析XMl文件之SAX和DOm方法
  6. RPC与RMI的区别
  7. 404错误、500错误、异常错误提示页面的拦截和自定义
  8. piap.windows io 监测attilax总结
  9. python勒索病毒代码_.Lucky后缀勒索病毒数据解密(示例代码)
  10. 那些让人“口吐芬芳”的APP登录骚操作?!!
  11. RSS阅读器FeedDemon使用方法
  12. 或许再过两年,ASML将可以自由给中国供应EUV光刻机
  13. html标签验证步骤,html标签验证视频教程
  14. 企业管理软件,真的以业务流程为中心?
  15. h.265系列快速操作指南_H2O-快速指南
  16. Search Help SE11
  17. 【Android】TypedArray——三个方法获取dimen返回值的类型
  18. 社区专家谈 12306 1
  19. 【Python】从爬虫开始吧——爬取妹子图整站
  20. windows10 No module named ‘win32con‘ 亲测解决

热门文章

  1. 关于minio文件服务器的使用
  2. 5G+AIoT当打之年,科技潮牌realme大奇袭
  3. flyme6 yunos android,Android版Flyme对比Flyme Powered by YunOS
  4. 哈工大计算机学院计算机组成原理,哈工大威海计算机学院计算机组成原理.ppt...
  5. 社保、公积金查询方式
  6. 位宽512bit显卡_6144 CUDA/512bit位宽 Maxwell架构曝光
  7. 综合布线工程常用计算简单公式
  8. python中奖号_Python输入数字并从预定义的lis中选择中奖号码
  9. 【LAB1-Ruijie】验证分别在console口和vty接口下的login、login local、no login的区别
  10. C#项目中如何引用Excel