tnblog
首页
登录

IdentityServer4 单点登陆

82人阅读 2019/12/18 17:02 总访问:1354 评论:0 手机 收藏
分类: 笔记

                 

                 
hello 大家好 又见面了 今天给大家分享一下 identityServer4
首选我们先来了解一下什么是identityServer.
什么是单点登录统一认证:假如某公司旗下有10个网站(比如各种管理网站:人事系统啊,财务系统啊,业绩系统啊等),我是该公司一管理员或者用户,按照传统网站模式是这样:我打开A网站
 输入账号密码 
然后进入到A网站办点事,办完之后,我有需要到B网站去办点事,这个时候又需要输入账号密码,假如你还要到C网站办点事,又再需要输入账号密码。。。。。
  为了解决这个问题,所以出现了单点登录统一认证:即 该改管理员 登录了其中一个网站得到了ids4的授权之后,他再登入该公司旗下其他网站的时候不需要在输入账号密码,能够直接进入后台办事! 这就是单点登录统一认证!
下面咋们就用代码来展示一下
第一步:新建一个net core 项目,如下图所示
第二步:引进安装依赖项:IdentityServer4,在项目里面打开工具 找到程序包控制管理台 用install-package IdentityServer4 进行下载
第三步:打开项目里面的调试如下图 设置该项目的地址
第四步:新建一个配置文件类:Config.cs  代码如下:
public class Config
    {        // 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 = "mvc",
                    ClientName = "MVC Client",
                    AllowedGrantTypes = GrantTypes.Implicit,//隐式方式
                    RequireConsent=false,//如果不需要显示否同意授权 页面 这里就设置为false
                    RedirectUris = { "http://localhost:5002/signin-oidc" },//登录成功后返回的客户端地址
                    PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },//注销登录后返回的客户端地址
                    AllowedScopes =//下面这两个必须要加吧 不太明白啥意思                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile
                    }
                }
            };
        }
    }
第五步: 在Startup.cs的ConfigureServices方法中注入Ids4服务,如下面红色部分代码:
public void ConfigureServices(IServiceCollection services)
        {
           
        }
  在Startup.cs的Configure方法中添加ids4服务中间件(注意要放在UseMvc之前就可以)
  app.UseIdentityServer();
  现在id4的配置基本完成 下面就是要用数据进行测试
 
添加DbContext类 名字叫:EFContext.cs ,代码如下(其中红色部分是我们待会需要添加的实体类,也就是对应数据库里面的用户表Admin)
public class EFContext : DbContext
    {        public EFContext(DbContextOptions<EFContext> options) : base(options)
        {
        }        #region 实体集  
             
        #endregion
    }
    新建一个实体类 把实体添加到上一个类中,也就是上一个类的红色部分
    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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddIdentityServer()//Ids4服务                
            .AddDeveloperSigningCredential()
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryClients(Config.GetClients());//把配置文件的Client配置资源放到内存
        }
接下来,我们就要写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")));//注入DbContext            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddIdentityServer()//Ids4服务                .AddDeveloperSigningCredential()
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryClients(Config.GetClients());//把配置文件的Client配置资源放到内存
          
        }
        
 接下来就是登陆界面  后台新建一个AccountController 控制器
 public class AccountController : Controller
    {        private IAdminService _adminService;//自己写的操作数据库Admin表的service
        private 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;
        }        /// <summary>
        /// 登录页面        /// </summary>        [HttpGet]        public async Task<IActionResult> Login(string returnUrl=null)
        {
            ViewData["returnUrl"] = returnUrl;            return View();
        }        /// <summary>
        /// 登录post回发处理        /// </summary>        [HttpPost]        public async Task<IActionResult> 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();
            }
        }
    }
    
    前台 新建一个view
   
  @{
    Layout = null;
}<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Login</title>
</head>
<body>
    <div align="center">
        <h1>统一认证登录中心</h1>
        <form action="/Account/Login" method="post">
            用户名:<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>
综上 IdentityServer4服务端的工作完成 
接下来就是部署客户端
前面两步的步骤都一样 同样是建Net Core项目 然后设置地址
下一步在Startup.cs的ConfigureServices方法中添加(主要用来配置认证中心ids4的及自己作为客户端的认证信息):
public void ConfigureServices(IServiceCollection services)
        {            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
            services.AddAuthentication(options =>
                {
                    options.DefaultScheme = "Cookies";
                    options.DefaultChallengeScheme = "oidc";
                })
                .AddCookie("Cookies")
                .AddOpenIdConnect("oidc", options =>
                {
                    options.SignInScheme = "Cookies";
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
                    options.ClientId = "mvc";
                    options.SaveTokens = true;
                });
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }
        
在 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>

最后启动项目就大功告成。

感谢你的观看 我们下期再见

创作不容易给个关注吧!

评价
不为失败找理由,只为成功找方法
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2020TNBLOG.NET