为认证服务端增加数据库支持
我计划使用一个名为Admin的表,放在一个已有的数据库里。所以我需要定义Admin类和在配置里预先加上数据库连接
新增类:Admin.cs
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; } }
配置上加上将要使用AdminContext的连接串,打开appsettings.json,添加红圈部分。可以按自己的数据库连接修改连接串。也可以不做这一部分,后面的过程IDE也会自己加上
在IdentityMvc项目的Controlers目录右键,选择“添加”=》“新搭建基架的项目”
选择“其操作使用Entity...的API控制器”
按“+”,添加数据上下文,修改图上的,添加后,修改控制器的名称为“AccountControler"
“添加”后,框架会修改startup.cs,添加几个文件。你可以自己看看修改的内容,弄明白Entity的一些机制。如果数据库没有这个表,我们可以进行以下操作,让框架帮我们去创建
点击菜单:工具=》NuGet包管理器=》程序包管理器控制台
Add-Migration CreateIdentitySchema Update-Database
Add-Migration
命令的 "CreateIdentitySchema" 名称参数是任意的
执行完上面的两个命令后,数据库访问就准备好了。现在要去修改AccountController,现在框架为我们生成的AccountCountroller并不是我们需要的,我们要整个替换掉
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using IdentityMvc.Data; using IdentityServer4.Services; using IdentityServer4.Stores; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace IdentityMvc.Controllers { public class AccountController : Controller { private readonly AdminContext _dbAdmin; 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, AdminContext db) { _interaction = interaction; _clientStore = clientStore; _schemeProvider = schemeProvider; _events = events; _dbAdmin = db; } /// <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 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(); } } /// <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 _dbAdmin.Admin.Where(a => a.UserName == username && a.Password == pwd).SingleOrDefaultAsync(); if (m != null) { return m; } else { return null; } } } }
如果你对于为什么Controller的构造函数放这么多参数,也希望看看哪里构造这个AccountController.其实是asp.net core的DI处理的,可以看看这文章
https://www.cnblogs.com/jesse2013/p/di-in-aspnetcore.html
好了,准备一下我们的Login视图就可测试了
在View目录下新增”Account"目录,右键Account目录,“添加”=》“视图”,录入Login名称,IDE将新建Login.cshtml,将其内容替换为如下代码:
@{ 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>
如果你都没有忽略什么的话,你应能在登录后看到界面回到首页下
但,如何你看到的是一个空白的页面,地址类似于https://localhost:44302/signin-oidc的页面,就说明,客户端ClientMvc的startup.cs文件的Configure方法少了一句: