!30 增加功能:增加第三方 OAuth 认证

* build: 依赖组件使用正式版
* feat: 增加 OAuth 认证
This commit is contained in:
Argo 2019-09-16 17:25:03 +08:00
parent 55900cc954
commit c3bbe488ea
43 changed files with 375 additions and 64 deletions

View File

@ -11,7 +11,7 @@
<ItemGroup>
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.2.21" />
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.16" />
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.17" />
<PackageReference Include="Longbow.Configuration" Version="2.2.7" />
<PackageReference Include="Longbow.Tasks" Version="2.2.23" />
<PackageReference Include="Microsoft.AspNetCore.App" />

View File

@ -1,11 +1,14 @@
using Bootstrap.Admin.Models;
using Bootstrap.DataAccess;
using Longbow.GiteeAuth;
using Longbow.GitHubAuth;
using Longbow.Web;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System;
using System.Linq;
using System.Net;
@ -30,7 +33,6 @@ namespace Bootstrap.Admin.Controllers
{
if (!User.Identity.IsAuthenticated) return Login();
var user = UserHelper.RetrieveUserByUserName(User.Identity.Name);
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var urlReferrer = Request.Headers["Referer"].FirstOrDefault();
return View(new LockModel(this)
@ -107,10 +109,11 @@ namespace Bootstrap.Admin.Controllers
/// Logout this instance.
/// </summary>
/// <returns>The logout.</returns>
[HttpGet]
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Redirect("~" + CookieAuthenticationDefaults.LoginPath);
await HttpContext.SignOutAsync();
return Redirect(Request.PathBase + CookieAuthenticationDefaults.LoginPath);
}
/// <summary>
@ -118,6 +121,29 @@ namespace Bootstrap.Admin.Controllers
/// </summary>
/// <returns>The denied.</returns>
[ResponseCache(Duration = 600)]
[HttpGet]
public ActionResult AccessDenied() => View("Error", ErrorModel.CreateById(403));
/// <summary>
/// Gitee 认证
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult Gitee([FromServices]IConfiguration config)
{
var enabled = config.GetValue($"{nameof(GiteeOptions)}:Eanbeld", false);
return Challenge(enabled ? GiteeDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
}
/// <summary>
/// GitHub 认证
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult GitHub([FromServices]IConfiguration config)
{
var enabled = config.GetValue($"{nameof(GitHubOptions)}:Eanbeld", false);
return Challenge(enabled ? GitHubDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}

View File

@ -3,6 +3,7 @@ using Bootstrap.Security;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Security.Principal;
namespace Bootstrap.Admin.Controllers
{
@ -48,7 +49,7 @@ namespace Bootstrap.Admin.Controllers
[HttpPost]
public BootstrapUser RetrieveUserByUserName([FromBody]string userName)
{
return UserHelper.RetrieveUserByUserName(userName);
return UserHelper.RetrieveUserByUserName(new GenericIdentity(userName));
}
/// <summary>
///

View File

@ -1,9 +1,10 @@
using Bootstrap.DataAccess;
using Bootstrap.DataAccess;
using Longbow.Web.SignalR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
namespace Bootstrap.Admin.Controllers.Api
@ -24,7 +25,7 @@ namespace Bootstrap.Admin.Controllers.Api
[HttpGet]
public bool Get(string userName)
{
return UserHelper.RetrieveUserByUserName(userName) == null && !UserHelper.RetrieveNewUsers().Any(u => u.UserName == userName);
return UserHelper.RetrieveUserByUserName(new GenericIdentity(userName)) == null && !UserHelper.RetrieveNewUsers().Any(u => u.UserName == userName);
}
/// <summary>
@ -57,7 +58,7 @@ namespace Bootstrap.Admin.Controllers.Api
[HttpPut]
public bool Put([FromBody]ResetUser user)
{
if (UserHelper.RetrieveUserByUserName(user.UserName) == null) return true;
if (UserHelper.RetrieveUserByUserName(new GenericIdentity(user.UserName)) == null) return true;
return UserHelper.ForgotPassword(user);
}
}

View File

@ -18,6 +18,7 @@ namespace Bootstrap.Admin.Controllers
public IActionResult Index()
{
var model = new HeaderBarModel(User.Identity);
if (string.IsNullOrEmpty(model.UserName)) return Redirect(Request.PathBase + CookieAuthenticationDefaults.LogoutPath);
var url = DictHelper.RetrieveHomeUrl(model.AppCode);
return url.Equals("~/Home/Index", System.StringComparison.OrdinalIgnoreCase) ? (IActionResult)View(model) : Redirect(url);
}
@ -39,4 +40,4 @@ namespace Bootstrap.Admin.Controllers
return View(model);
}
}
}
}

View File

@ -5,6 +5,7 @@ using Microsoft.Extensions.Diagnostics.HealthChecks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Task = System.Threading.Tasks.Task;
@ -68,7 +69,7 @@ namespace Bootstrap.Admin.HealthChecks
try
{
DbContextManager.Exception = null;
var user = UserHelper.RetrieveUserByUserName(userName);
var user = UserHelper.RetrieveUserByUserName(new GenericIdentity(userName));
displayName = user?.DisplayName;
roles = string.Join(",", RoleHelper.RetrievesByUserName(userName) ?? new string[0]);
menusCount = MenuHelper.RetrieveMenusByUserName(userName)?.Count() ?? 0;

View File

@ -1,4 +1,5 @@
using Bootstrap.DataAccess;
using System;
using System.Security.Principal;
namespace Bootstrap.Admin.Models
@ -14,13 +15,16 @@ namespace Bootstrap.Admin.Models
/// <param name="identity"></param>
public HeaderBarModel(IIdentity identity)
{
var user = UserHelper.RetrieveUserByUserName(identity.Name);
Icon = string.Format("{0}{1}", DictHelper.RetrieveIconFolderPath(), user.Icon);
DisplayName = user.DisplayName;
UserName = user.UserName;
AppCode = user.App;
Css = user.Css;
ActiveCss = string.IsNullOrEmpty(Css) ? Theme : Css;
var user = UserHelper.RetrieveUserByUserName(identity);
if (user != null)
{
Icon = user.Icon.Contains("://", StringComparison.OrdinalIgnoreCase) ? user.Icon : string.Format("{0}{1}", DictHelper.RetrieveIconFolderPath(), user.Icon);
DisplayName = user.DisplayName;
UserName = user.UserName;
AppCode = user.App;
Css = user.Css;
ActiveCss = string.IsNullOrEmpty(Css) ? Theme : Css;
}
}
/// <summary>
@ -53,4 +57,4 @@ namespace Bootstrap.Admin.Models
/// </summary>
public string ActiveCss { get; }
}
}
}

View File

@ -3,12 +3,12 @@
namespace Bootstrap.Admin.Models
{
/// <summary>
///
/// 登陆页面 Model
/// </summary>
public class LoginModel : ModelBase
{
/// <summary>
///
/// 默认构造函数
/// </summary>
public LoginModel()
{
@ -21,7 +21,7 @@ namespace Bootstrap.Admin.Models
public string ImageLibUrl { get; protected set; }
/// <summary>
/// 是否登录认证失败
/// 是否登录认证失败 为真时客户端弹出滑块验证码
/// </summary>
public bool AuthFailed { get; set; }
}

View File

@ -20,6 +20,11 @@ namespace Bootstrap.Admin.Models
/// </summary>
public string FileName { get; }
/// <summary>
/// 获得 是否为第三方用户
/// </summary>
public bool External { get; }
/// <summary>
///
/// </summary>
@ -39,6 +44,8 @@ namespace Bootstrap.Admin.Models
FileName = Path.GetFileName(fileName);
}
}
if (controller.User.Identity.AuthenticationType != Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme) External = true;
}
}
}
}

View File

@ -1,4 +1,5 @@
using Bootstrap.DataAccess;
using Longbow.GiteeAuth;
using Longbow.Web;
using Longbow.Web.SignalR;
using Microsoft.AspNetCore.Builder;
@ -60,7 +61,7 @@ namespace Bootstrap.Admin
services.AddSignalR().AddJsonProtocalDefault();
services.AddSignalRExceptionFilterHandler<SignalRHub>((client, ex) => client.SendMessageBody(ex).ConfigureAwait(false));
services.AddResponseCompression();
services.AddBootstrapAdminAuthentication();
services.AddBootstrapAdminAuthentication().AddGitee(OAuthHelper.Configure).AddGitHub(OAuthHelper.Configure);
services.AddSwagger();
services.AddButtonAuthorization(MenuHelper.AuthorizateButtons);
services.AddBootstrapAdminBackgroundTask();

View File

@ -43,10 +43,10 @@
}
<div class="container">
<input id="imgUrl" type="hidden" value="@Model.ImageLibUrl" />
<form id="login" method="post" class="form-signin">
<form id="login" method="post" class="form-signin" data-demo="True">
<h2 class="form-signin-heading">@Model.Title</h2>
<div class="login-wrap" data-auth="@Model.AuthFailed" data-toggle="LgbValidate" data-valid-button="button[type='submit']">
<div class="alert alert-danger" asp-condition="@Model.AuthFailed">用户名或密码错误!</div>
<div class="alert alert-danger d-none" asp-condition="@Model.AuthFailed">用户名或密码错误!</div>
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
@ -54,7 +54,7 @@
<span class="fa fa-user"></span>
</div>
</div>
<input type="text" name="userName" class="form-control" placeholder="用户名" maxlength="16" data-required-msg="请输入用户名" value="@ViewBag.UserName" autofocus data-valid="true" />
<input type="text" name="userName" class="form-control" placeholder="用户名" maxlength="16" data-required-msg="请输入用户名" value="" autofocus data-valid="true" />
</div>
</div>
<div class="form-group">
@ -64,7 +64,7 @@
<span class="fa fa-lock"></span>
</div>
</div>
<input type="password" name="password" class="form-control" value="@ViewBag.Password" placeholder="密码" maxlength="16" data-required-msg="请输入密码" data-valid="true" />
<input type="password" name="password" class="form-control" value="" placeholder="密码" maxlength="16" data-required-msg="请输入密码" data-valid="true" />
</div>
</div>
<div class="form-group rememberPwd" onselectstart="return false">
@ -72,11 +72,43 @@
<span>记住密码自动登录</span>
<input id="remember" name="remember" type="hidden" value="false" />
</div>
<button class="btn btn-lg btn-login btn-block" type="submit">登 录</button>
<button class="btn btn-lg btn-login btn-block" data-toggle="tooltip" title="不填写密码默认使用 Gitee 认证" type="submit">登 录</button>
<div class="login-footer">
<a href="#" data-method="register">申请账号</a>
<a href="#" data-method="forgot">忘记密码</a>
</div>
<div class="login-other">
<span class="text-muted">
其他方式登录
</span>
</div>
<div class="login-list">
<div class="item">
<a href="~/Account/Gitee" data-toggle="tooltip" title="使用 Gitee 帐号登录">
<img class="item" src="~/images/gitee.svg" />
</a>
</div>
<div class="item">
<a href="~/Account/GitHub" data-toggle="tooltip" title="使用 GitHub 帐号登录">
<img class="item" src="~/images/git.svg" />
</a>
</div>
<div class="item">
<a href="#" data-toggle="tooltip" title="微信-暂未实现">
<img class="item" src="~/images/weixin-2.svg" />
</a>
</div>
<div class="item">
<a href="#" data-toggle="tooltip" title="QQ-暂未实现">
<img class="item" src="~/images/qq-2.svg" />
</a>
</div>
<div class="item">
<a href="#" data-toggle="tooltip" title="支付宝-暂未实现">
<img class="item" src="~/images/zhifubao-2.svg" />
</a>
</div>
</div>
<div class="slidercaptcha card">
<div class="card-header">
<span>请完成安全验证</span>

View File

@ -53,7 +53,7 @@
</div>
</div>
</div>
<div class="card" asp-auth="savePassword">
<div class="card" asp-auth="savePassword" asp-condition="!@Model.External">
<div class="card-header">修改密码</div>
<div class="card-body" data-toggle="LgbValidate" data-valid-button="#btnSavePassword">
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">

View File

@ -60,6 +60,28 @@
"Folder": "TaskStorage",
"Secure": false
},
"GiteeOptions": {
"Enabled": true,
"ClientId": "9bfe9b95d813ca7d613b110a54eda28bf227154b314c95f0c69e7680d64525e1",
"ClientSecret": "3427f2d901ba9afc76c1842a7303b2d67f8e098e71acc15051f89fe6f3d265db",
"CallbackPath": "/signin-gitee",
"HomePath": "/Admin/Profiles",
"Scope": [ "user_info", "projects" ],
"Roles": [ "Administrators" ],
"App": "0",
"StarredUrl": "https://gitee.com/api/v5/user/starred/LongbowEnterprise/BootstrapAdmin"
},
"GitHubOptions": {
"Enabled": true,
"ClientId": "ec53ecfe238558a0423b",
"ClientSecret": "ffa759ca599df941b869efecb5e750bc1b27334e",
"CallbackPath": "/signin-github",
"HomePath": "/Admin/Profiles",
"Scope": [ "user_info", "repo" ],
"Roles": [ "Administrators" ],
"App": "0",
"StarredUrl": "https://api.github.com/user/starred/ArgoZhang/BootstrapAdmin"
},
"LongbowCache": {
"Enabled": true,
"CorsItems": [

View File

@ -66,6 +66,26 @@
"Folder": "TaskStorage",
"Secure": true
},
"GiteeOptions": {
"Eanbeld": true,
"ClientId": "<ClientId>",
"ClientSecret": "<ClientSecret>",
"CallbackPath": "/signin-gitee",
"HomePath": "/Home/Index",
"Scope": [ "user_info", "projects" ],
"Roles": [ "Default" ],
"App": "2"
},
"GitHubOptions": {
"Eanbeld": true,
"ClientId": "<ClientId>",
"ClientSecret": "<ClientSecret>",
"CallbackPath": "/signin-github",
"HomePath": "/Home/Index",
"Scope": [ "user_info", "repo" ],
"Roles": [ "Default" ],
"App": "2"
},
"LongbowCache": {
"Enabled": true,
"CorsItems": [

View File

@ -31,26 +31,30 @@
.login-wrap {
padding: 0;
margin: 36px 0 0 370px;
margin: 18px 0 0 370px;
width: 280px;
}
.slidercaptcha {
top: -254px;
top: -272px;
left: -15px;
}
.slidercaptcha.card .card-body {
padding: 15px 15px 0 15px;
}
.slidercaptcha, .slidercaptcha.forgot {
width: 310px;
height: 280px;
}
.login-wrap[data-auth="True"] {
margin: 12px 0 0 370px;
margin: 20px 0 0 370px;
}
.login-wrap[data-auth="True"] .slidercaptcha {
top: -282px;
top: -264px;
}
.login-wrap[data-auth="True"] .slidercaptcha, .slidercaptcha.forgot {

View File

@ -14,7 +14,7 @@
.login-wrap {
padding: 20px;
height: 270px;
height: 300px;
}
.login-wrap .rememberPwd {
@ -27,8 +27,8 @@
width: 13px;
}
.login-wrap[data-auth="True"] {
height: 330px;
.login-wrap .card {
border-top-width: 1px;
}
.login-footer a:last-child {
@ -42,9 +42,10 @@
font-weight: 300;
font-family: 'Open Sans', sans-serif;
box-shadow: 0 4px #e56b60;
margin-bottom: 20px;
margin-bottom: 0.625rem;
outline: none !important;
margin-top: -4px;
margin-top: -0.5rem;
line-height: 1;
}
.btn-login:focus {
@ -67,8 +68,8 @@
box-shadow: 0 0 10px #fff;
left: 0;
right: 0;
top: -232px;
height: 234px;
top: -270px;
height: 226px;
}
.slidercaptcha canvas:first-child {
@ -81,6 +82,10 @@
margin-top: -2px;
}
.slidercaptcha.card .card-body {
padding: 0.625rem 0 0 0;
}
.slidercaptcha.card .card-header {
background-image: none;
background-color: rgba(0, 0, 0, 0.03);
@ -104,3 +109,38 @@
.slidercaptcha.reg {
bottom: 60px;
}
.login-other {
display: table;
text-align: center;
white-space: nowrap;
margin: 0.25rem 0 0.625rem 0;
}
.login-other:before, .login-other:after {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC");
content: '';
display: table-cell;
position: relative;
top: 50%;
width: 50%;
background-repeat: no-repeat;
}
.login-other:before {
background-position: right 1em top 50%;
}
.login-other:after {
background-position: left 1em top 50%;
}
.login-list {
display: flex;
justify-content: space-between;
}
.login-list .item {
width: 32px;
height: 32px;
}

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 34.133333c263.918933 0 477.866667 213.947733 477.866667 477.866667s-213.947733 477.866667-477.866667 477.866667S34.133333 775.918933 34.133333 512 248.081067 34.133333 512 34.133333z m307.2 564.224v-176.981333a101.376 101.376 0 0 0-101.410133-101.376h-134.2464l32.392533 45.841067 97.860267 29.969066c18.158933 5.7344 29.696 22.562133 29.5936 40.618667v146.8416a42.325333 42.325333 0 0 1-29.5936 40.618667l-97.860267 30.0032-32.426667 45.841066h134.280534A101.376 101.376 0 0 0 819.2 598.357333z m-405.981867-66.628266h202.922667v-45.738667h-202.922667v45.738667zM311.569067 699.733333h134.2464l-32.392534-45.841066-97.860266-30.0032a42.325333 42.325333 0 0 1-29.559467-40.618667V436.565333v-0.1024a42.325333 42.325333 0 0 1 29.559467-40.618666l97.860266-30.037334 32.426667-45.806933H311.534933a101.376 101.376 0 0 0-101.410133 101.376v176.9472A101.376 101.376 0 0 0 311.569067 699.733333z" fill="#515151" /></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M514.304 3.072c-281.344 0-509.44 228.096-509.44 509.44s228.096 509.44 509.44 509.44 509.44-228.096 509.44-509.44-228.096-509.44-509.44-509.44z m221.184 438.016c-1.024 4.096-3.328 10.24-6.656 17.408l-0.512 0.768c-19.712 42.24-71.168 125.184-71.168 125.184s0-0.256-0.256-0.512l-15.104 26.112H714.24l-138.496 184.576 31.488-125.44h-57.088l19.712-82.944c-16.128 3.84-35.072 9.216-57.6 16.384 0 0-30.464 17.92-87.552-34.304 0 0-38.656-34.048-16.128-42.496 9.472-3.584 46.08-8.192 75.008-12.032 38.912-5.12 62.976-8.192 62.976-8.192s-120.064 1.792-148.736-2.56c-28.416-4.352-64.768-52.224-72.448-93.952 0 0-12.032-23.04 25.6-12.032s192.768 42.24 192.768 42.24-201.984-61.952-215.296-77.056c-13.312-15.104-39.424-82.688-36.096-124.16 0 0 1.536-10.24 12.032-7.68 0 0 149.248 68.352 251.392 105.728 102.4 37.632 191.232 56.576 179.712 104.96z" fill="#3AABF9" /></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M722.579864 496.275801H481.439296v-179.19996l240.799235-34.952526 0.341333 214.12973z m0 243.711946l-241.140568-34.702215v-179.996404h240.913013l0.227555 214.721374zM452.562502 492.08878h-182.431248v-147.842812l182.658804-24.80355-0.227556 172.646362z m0 209.737908l-182.431248-25.167638v-151.460944h182.431248v176.628582zM874.018053 150.004589A510.998642 510.998642 0 0 0 512.022756 0 510.998642 510.998642 0 0 0 150.027458 150.004589c-200.021289 200.499155-200.021289 523.491439 0 723.990595A510.998642 510.998642 0 0 0 512 1023.999772a510.998642 510.998642 0 0 0 361.995297-150.004588c199.975778-200.521911 199.975778-523.468684 0-723.990595z" fill="#1296db" /></svg>

After

Width:  |  Height:  |  Size: 937 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M0 520.886c0-69.368 13.51-135.697 40.498-199.02 26.987-63.323 63.322-117.826 109.006-163.51 45.65-45.65 100.154-81.985 163.51-109.006A502.289 502.289 0 0 1 512 8.92c69.335 0 135.663 13.477 198.986 40.497 63.356 26.988 117.86 63.323 163.51 109.007 45.684 45.65 82.02 100.154 109.006 163.51A502.289 502.289 0 0 1 1024 520.852c0 111.318-32.504 211.472-97.511 300.494-64.975 88.989-148.48 150.825-250.484 185.476-5.351 0-9.348-0.99-11.99-2.973-2.676-1.982-4.196-3.997-4.526-6.012a59.458 59.458 0 0 1-0.495-8.984 7.663 7.663 0 0 1-0.991-3.006v-128.99c0-40.63-14.336-75.314-43.008-103.986 76.667-13.345 134.011-41.819 171.999-85.487 37.987-43.669 57.013-96.52 57.013-158.522 0-58.005-18.663-108.346-56.022-150.99 13.345-42.678 11-87.668-6.97-135.003-18.697-1.322-39.011 1.85-61.01 9.513-22 7.663-38.318 14.831-49.02 21.47-10.637 6.673-20.316 13.016-28.97 19.027-38.68-10.669-81.854-16.02-129.486-16.02-47.7 0-90.509 5.351-128.529 16.02-7.333-5.35-15.855-11.164-25.5-17.507-9.68-6.342-26.493-14.005-50.507-22.99-23.982-9.018-45.65-12.85-65.008-11.495-18.663 47.996-20.645 93.646-5.979 136.984-36.665 42.678-54.998 92.986-54.998 150.99 0 62.002 18.663 114.689 55.99 157.994 37.326 43.339 94.67 72.01 171.998 86.016a142.303 142.303 0 0 0-39.969 70.029c-56.683 13.972-96.355 3.963-119.015-30.06-42.017-61.308-79.674-83.307-113.003-65.965-4.69 4.657-3.997 9.48 1.982 14.501 6.012 4.988 14.996 11.66 27.02 19.985 11.99 8.357 20.976 17.507 26.987 27.515 0.661 1.322 2.51 6.177 5.517 14.502a831.917 831.917 0 0 0 8.985 23.981c2.973 7.663 8.654 16.186 17.011 25.5 8.324 9.349 18.003 17.178 29.003 23.52 11 6.309 26.161 11 45.485 14.006 19.324 2.972 41.323 3.138 65.998 0.495v100.484c0 0.991-0.165 2.643-0.495 5.021-0.33 2.312-0.991 3.964-1.982 4.955-0.991 1.024-2.345 2.015-4.03 3.039a12.52 12.52 0 0 1-6.474 1.486c-2.676 0-6.012-0.33-10.009-0.99-101.343-35.345-183.825-97.182-247.51-185.51C31.842 731.037 0 631.577 0 520.92z" /></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 1024C229.234 1024 0 794.766 0 512S229.234 0 512 0s512 229.234 512 512-229.234 512-512 512z m259.157-568.889l-290.759 0.014c-13.966 0-25.287 11.321-25.287 25.273l-0.028 63.218c0 13.966 11.306 25.287 25.273 25.287H657.38c13.966 0 25.287 11.307 25.287 25.273v12.644a75.847 75.847 0 0 1-75.847 75.847H366.606a25.287 25.287 0 0 1-25.287-25.273v-240.2a75.847 75.847 0 0 1 75.847-75.846l353.92-0.015c13.966 0 25.273-11.306 25.287-25.273l0.071-63.189c0-13.966-11.306-25.287-25.272-25.301l-353.992 0.014c-104.718-0.014-189.624 84.892-189.624 189.61v353.963c0 13.967 11.32 25.287 25.287 25.287h372.935c94.265 0 170.666-76.401 170.666-170.666v-145.38c0-13.952-11.32-25.273-25.287-25.273z" fill="#d81e06" /></svg>

After

Width:  |  Height:  |  Size: 973 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 0C229.2224 0 0 229.21728 0 512s229.2224 512 512 512 512-229.21728 512-512S794.7776 0 512 0z m281.89696 671.57504c-13.22496 12.34432-35.92192-1.10592-57.74336-31.29856a330.44992 330.44992 0 0 1-36.1472 70.30784c30.85312 11.01824 50.69312 28.2112 50.69312 47.61088 0 33.50016-59.2896 60.61056-132.45952 60.61056-43.4176 0-81.77152-9.47712-106.01472-24.2432-24.02304 14.76608-62.592 24.2432-106.01472 24.2432-73.17504 0-132.45952-27.1104-132.45952-60.61056 0-19.1744 19.83488-36.58752 50.69312-47.61088-14.54592-21.16096-26.66496-44.74368-36.14208-70.30784-21.82144 29.97248-44.52352 43.63776-57.74336 31.29856-18.0736-16.9728-11.24352-76.92288 15.64672-133.7856 6.1696-13.0048 12.78464-24.68352 19.61472-34.82112 3.74784-165.30432 112.62976-297.98912 246.19008-297.98912h0.44032c133.56544 0 242.44736 132.45952 246.19008 297.98912 6.8352 10.1376 13.44 21.82144 19.61472 34.82112 26.65984 56.86272 33.7152 116.8128 15.6416 133.7856z" fill="#8a8a8a" /></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 0C229.2224 0 0 229.21728 0 512s229.2224 512 512 512 512-229.21728 512-512S794.7776 0 512 0z m281.89696 671.57504c-13.22496 12.34432-35.92192-1.10592-57.74336-31.29856a330.44992 330.44992 0 0 1-36.1472 70.30784c30.85312 11.01824 50.69312 28.2112 50.69312 47.61088 0 33.50016-59.2896 60.61056-132.45952 60.61056-43.4176 0-81.77152-9.47712-106.01472-24.2432-24.02304 14.76608-62.592 24.2432-106.01472 24.2432-73.17504 0-132.45952-27.1104-132.45952-60.61056 0-19.1744 19.83488-36.58752 50.69312-47.61088-14.54592-21.16096-26.66496-44.74368-36.14208-70.30784-21.82144 29.97248-44.52352 43.63776-57.74336 31.29856-18.0736-16.9728-11.24352-76.92288 15.64672-133.7856 6.1696-13.0048 12.78464-24.68352 19.61472-34.82112 3.74784-165.30432 112.62976-297.98912 246.19008-297.98912h0.44032c133.56544 0 242.44736 132.45952 246.19008 297.98912 6.8352 10.1376 13.44 21.82144 19.61472 34.82112 26.65984 56.86272 33.7152 116.8128 15.6416 133.7856z" fill="#1296db" /></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 1024C229.2224 1024 0 794.7776 0 512S229.2224 0 512 0s512 229.2224 512 512-229.2224 512-512 512z m-51.2-245.76c175.3088 0 316.0832-91.6992 316.0832-204.8 0-95.5648-119.68-95.5648-119.68-101.7344 0-6.144 59.5968-61.6704 0-96.2048s-168.576 17.9712-165.2992 12.3392c46.8736-80.64-20.1216-106.0864-54.272-106.0864-81.408 0-294.272 178.5856-294.272 291.6864s142.1312 204.8 317.44 204.8z m24.832-35.5328c-112.0256 15.744-211.1232-30.5152-221.3376-103.3216s72.2688-144.5888 184.2688-160.3328c112-15.744 211.0976 30.5152 221.3376 103.3216s-72.2688 144.5888-184.2688 160.3328z m-19.968-25.472c66.6112-12.9536 111.872-68.4544 101.0944-123.9552-10.8032-55.5264-73.5488-90.0352-140.16-77.056-66.6368 12.928-111.872 68.4288-101.0944 123.9296 10.8032 55.5264 73.5488 90.0352 140.16 77.0816zM450.56 593.92a20.48 20.48 0 1 1 0-40.96 20.48 20.48 0 0 1 0 40.96z m-38.0672 61.1584c-20.5056 9.5488-42.9568 4.8384-50.1248-10.5472-7.168-15.36 3.6352-35.584 24.1408-45.1328 20.5056-9.5744 42.9312-4.864 50.1248 10.496 7.168 15.4112-3.6608 35.6096-24.1408 45.184zM734.9248 326.144c-36.992-33.28-74.8032-21.888-74.8032-21.888a29.312 29.312 0 0 0-25.2416 28.3648v-15.872c0 14.08 11.4432 24.7552 25.7536 24.96 0 0 29.8752-5.6832 49.6128 17.7408 19.7376 23.4496 6.656 50.816 6.656 50.816-3.6608 13.4912 4.7104 24.448 18.9696 24.448h-8.064c14.1568 0 27.776-11.2384 29.4912-25.088 0 0 14.6432-50.176-22.3744-83.456z m69.0944-66.6112c-67.84-64.1536-151.3472-54.5792-151.3472-54.5792A38.272 38.272 0 0 0 614.4 243.4048V220.928c0 21.3248 16.9472 37.888 38.4256 38.2208 0 0 79.616-10.368 120.3456 48.0512s24.576 115.2 24.576 115.2c-2.6624 21.12 12.3392 38.2208 33.4592 38.2208h-22.2976c21.1456 0 40.5248-16.896 42.1888-38.4 0 0 20.7616-98.5344-47.104-162.688z" fill="#FF5222" /></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="199.80px" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M504.5 417.262c14.997 0 24.939-10.008 24.939-24.944 0-14.99-9.93-24.863-24.94-24.863-14.94 0-29.93 9.862-29.93 24.863 0.003 14.936 14.994 24.944 29.93 24.944zM569.296 511.982c-9.927 0-19.941 10.007-19.941 19.949 0 10.069 10.018 19.923 19.941 19.923 15.078 0 24.944-9.854 24.944-19.923 0-9.942-9.87-19.95-24.944-19.95zM365.032 367.455c-14.928 0-30.006 9.862-30.006 24.863 0 14.936 15.078 24.944 30.006 24.944s24.871-10.008 24.882-24.944c0-14.99-9.953-24.863-24.882-24.863zM678.916 511.982c-9.858 0-19.8 10.007-19.8 19.949 0 10.069 9.942 19.923 19.8 19.923 14.93 0 24.943-9.854 24.943-19.923 0-9.942-10.018-19.95-24.943-19.95z" fill="#8a8a8a" /><path d="M512 0C229.232 0 0 229.232 0 512.004 0 794.77 229.232 1024 512 1024c282.771 0 512.007-229.229 512.007-511.996C1024.007 229.232 794.771 0 512 0z m-82.258 621.685c-24.87 0-44.863-5.063-69.799-10.014l-69.66 34.954 19.93-59.959c-49.864-34.809-79.726-79.733-79.726-134.469 0-94.807 89.73-169.48 199.277-169.48 97.987 0 183.813 59.653 201.056 139.932-6.352-0.702-12.74-1.179-19.193-1.179-94.658 0-169.43 70.658-169.43 157.666 0 14.474 2.263 28.42 6.148 41.756-6.144 0.488-12.353 0.793-18.603 0.793z m293.975 69.792l14.991 49.806-54.666-29.93c-19.938 5.005-39.942 9.996-59.788 9.996-94.812 0-169.492-64.8-169.492-144.6 0-79.62 74.677-144.555 169.492-144.555 89.536 0 169.258 64.939 169.258 144.556 0.004 44.946-29.803 84.738-69.795 114.727z" fill="#8a8a8a" /></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="199.80px" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M511.489531 513.531406m-510.468594 0a510.468594 510.468594 0 1 0 1020.937189 0 510.468594 510.468594 0 1 0-1020.937189 0Z" fill="#26A92E" /><path d="M629.407777 406.333001c7.657029 0 15.314058 0.510469 22.971086 1.531406-20.418744-94.947159-122.001994-165.902293-238.388833-165.902293-129.659023 0-235.836491 88.311067-235.836491 200.614157 0 64.829511 35.222333 117.918245 94.43669 159.266202l-23.481555 70.955134 82.695912-41.347956c29.607178 5.615155 53.088734 11.740778 82.695913 11.740778 7.657029 0 14.803589-0.510469 21.950149-1.020937-4.594217-15.824526-7.14656-32.159521-7.14656-49.515454-0.510469-102.604187 88.311067-186.321037 200.103689-186.321037zM502.811565 342.524427c17.866401 0 29.607178 11.740778 29.607179 29.607178s-11.740778 29.607178-29.607179 29.607179-35.222333-11.740778-35.222333-29.607179c-0.510469-18.376869 17.355932-29.607178 35.222333-29.607178zM337.419741 401.228315c-17.866401 0-35.732802-11.740778-35.732802-29.607178s17.866401-29.607178 35.732802-29.607179 29.607178 11.740778 29.607178 29.607179-11.740778 29.607178-29.607178 29.607178z m507.405782 188.87338c0-94.43669-94.43669-171.006979-200.614157-171.006979-112.303091 0-200.614158 77.080758-200.614158 171.006979 0 94.43669 88.311067 171.006979 200.614158 171.006979 23.481555 0 47.473579-6.125623 70.955134-11.740778l64.829512 35.732802-17.866401-59.214357c47.473579-35.222333 82.695912-82.185444 82.695912-135.784646z m-265.443669-29.607179c-11.740778 0-23.481555-11.740778-23.481555-23.481555s11.740778-23.481555 23.481555-23.481555c17.866401 0 29.607178 11.740778 29.607179 23.481555 0 12.251246-11.740778 23.481555-29.607179 23.481555z m129.659023 0c-11.740778 0-23.481555-11.740778-23.481555-23.481555s11.740778-23.481555 23.481555-23.481555c17.866401 0 29.607178 11.740778 29.607179 23.481555 0 12.251246-11.740778 23.481555-29.607179 23.481555z" fill="#FFFFFF" /></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M233.296349 578.657268a76.433787 76.433787 0 0 0-28.66267 41.783804 86.582495 86.582495 0 0 0 22.632894 79.278822 150.489633 150.489633 0 0 0 91.126059 38.556599 241.785545 241.785545 0 0 0 146.795333-50.573689 324.079255 324.079255 0 0 0 70.064305-69.384893 432.487843 432.487843 0 0 0-211.721589-60.934713 209.08887 209.08887 0 0 0-90.234332 21.27407zM982.559774 713.647828a511.936517 511.936517 0 1 0-56.391149 99.278996 56591.023592 56591.023592 0 0 0-320.809588-158.51518 395.247603 395.247603 0 0 1-176.010025 117.920347 253.335539 253.335539 0 0 1-126.582843 9.724076 167.942014 167.942014 0 0 1-89.979552-47.431411 170.235028 170.235028 0 0 1-27.049068-37.962114l1.18897 3.014889a91.041133 91.041133 0 0 1-7.685842-19.40569 87.134517 87.134517 0 0 1-3.312131-18.046866 94.820359 94.820359 0 0 1 0-12.993744 94.3108 94.3108 0 0 1 1.656066-23.949253A122.378985 122.378985 0 0 1 212.489374 560.100844 204.290526 204.290526 0 0 1 360.558604 509.824397a781.535468 781.535468 0 0 1 210.787398 48.153286 751.981071 751.981071 0 0 0 41.783804-120.510604h-305.310515v-32.866528h156.774189V338.612715H274.952763V305.576334h189.640717V239.588498c0-9.044665 1.783455-16.475727 16.518191-16.475727h74.268163V305.576334h206.286297v33.036381h-206.286297v65.987836h165.012052a648.243437 648.243437 0 0 1-68.365776 183.441088c114.990386 41.104392 276.775234 104.374582 330.533664 125.606189z" fill="#8a8a8a" /></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M211.03874656 682.3954475a101.7592875 101.7592875 0 0 1 83.03941875-104.63926781c104.63926781-17.27987906 248.63826 69.5995125 248.63826 69.5995125a312.47781281 312.47781281 0 0 1-226.55841469 126.71911312c-60.95957344-4.31997-104.63926781-39.35972437-104.63926687-91.67935781z m741.59480906 35.03975438c-12.95990906-4.31997-309.5978325-95.99932781-300.95789343-104.63926782a573.11598844 573.11598844 0 0 0 73.9194825-174.71877656v-26.39981531h-174.71877657V346.39779875h213.59850469v-39.35972437h-213.59850469v-95.99932782H463.99697562v91.67935875H271.99832v39.35972438h191.99865562v65.2795425H311.35804437v26.39981531h313.9178025a536.63624344 536.63624344 0 0 1-43.67969437 139.67902219A709.43503406 709.43503406 0 0 0 358.87771156 511.99664c-83.03941875 4.31997-148.31896219 30.71978531-179.03874656 91.67935781-43.67969437 113.27920687 26.39981531 227.03841094 183.35871656 227.03841094a331.19768156 331.19768156 0 0 0 248.63826-143.99899219c26.39981531 12.95990906 174.23878031 87.35938875 265.91813813 135.35905313A473.27668687 473.27668687 0 0 1 511.99664 991.99328a479.99664 479.99664 0 1 1 479.99664-479.99664 442.5569025 442.5569025 0 0 1-39.35972437 204.95856563z m0 0" fill="#19A0E5" /></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -26,10 +26,10 @@
});
},
capWidth: function () {
return $(window).width() < 768 ? 216 : 280;
return $(window).width() < 768 ? 256 : 280;
},
capHeight: function () {
return $(window).width() < 768 ? 110 : 150;
return $(window).width() < 768 ? 106 : 150;
},
capRegSuccess: function () {
$.bc({
@ -116,4 +116,16 @@
}
}
});
// use Gitee authentication when SystemDemoModel
var $login = $('#login');
if ($login.attr('data-demo') === 'True') {
$login.find('[data-valid="true"]').attr('data-valid', 'false');
$login.on('submit', function (e) {
if ($('[name="userName"]').val() === '' && $('[name="password"]').val() === '') {
location.href = "Gitee";
e.preventDefault();
}
});
}
});

View File

@ -4,6 +4,7 @@ using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
namespace Bootstrap.DataAccess.MongoDB
{
@ -104,7 +105,7 @@ namespace Bootstrap.DataAccess.MongoDB
public override bool Save(DataAccess.User user)
{
// 已经存在或者已经在新用户中了
if (UserHelper.RetrieveUserByUserName(user.UserName) != null || UserHelper.RetrieveNewUsers().Any(u => u.UserName == user.UserName)) return false;
if (UserHelper.RetrieveUserByUserName(new GenericIdentity(user.UserName)) != null || UserHelper.RetrieveNewUsers().Any(u => u.UserName == user.UserName)) return false;
DbManager.Users.InsertOne(new User()
{

View File

@ -6,12 +6,14 @@
<ItemGroup>
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.2.21" />
<PackageReference Include="Longbow.Configuration" Version="2.2.7" />
<PackageReference Include="Longbow.Data" Version="2.3.7" />
<PackageReference Include="Longbow.GiteeAuth" Version="2.2.0" />
<PackageReference Include="Longbow.GitHubAuth" Version="2.2.0" />
<PackageReference Include="Longbow.Logging" Version="2.2.13" />
<PackageReference Include="Longbow.PetaPoco" Version="1.0.2" />
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
<PackageReference Include="Longbow.Web" Version="2.2.16" />
<PackageReference Include="Longbow.Cache" Version="2.2.15" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.6" />
<PackageReference Include="PetaPoco.Extensions" Version="1.0.9" />
</ItemGroup>

View File

@ -48,9 +48,14 @@ namespace Bootstrap.DataAccess
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
});
cacheKeys.Add(UserHelper.RetrieveNewUsersDataKey + "*");
cacheKeys.Add(UserHelper.RetrieveUsersDataKey + "*");
corsKeys.Add(UserHelper.RetrieveUsersDataKey + "*");
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
cacheKeys.Add(UserHelper.RetrieveUsersDataKey);
cacheKeys.Add(GroupHelper.RetrieveGroupsByUserNameDataKey + "*");
cacheKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
cacheKeys.Add(AppHelper.RetrieveAppsByUserNameDataKey + "*");
corsKeys.Add(UserHelper.RetrieveUsersDataKey);
corsKeys.Add(GroupHelper.RetrieveGroupsByUserNameDataKey + "*");
corsKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
corsKeys.Add(AppHelper.RetrieveAppsByUserNameDataKey + "*");
}
if (groupIds != null)
{

View File

@ -5,15 +5,19 @@ using System.Collections.Generic;
namespace Bootstrap.DataAccess
{
/// <summary>
///
/// 前台应用帮助类
/// </summary>
public static class AppHelper
{
/// <summary>
///
/// 通过角色 ID 获得授权前台应用数据缓存键值
/// </summary>
public const string RetrieveAppsByRoleIdDataKey = "AppHelper-RetrieveAppsByRoleId";
/// <summary>
/// 通过用户名称获得授权前台应用数据缓存键值
/// </summary>
public const string RetrieveAppsByUserNameDataKey = DbHelper.RetrieveAppsByUserNameDataKey;
/// <summary>
/// 根据角色ID指派应用程序
/// </summary>
@ -39,6 +43,6 @@ namespace Bootstrap.DataAccess
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public static IEnumerable<string> RetrievesByUserName(string userName) => CacheManager.GetOrAdd($"{DbHelper.RetrieveAppsByUserNameDataKey}-{userName}", key => DbContextManager.Create<App>().RetrievesByUserName(userName), DbHelper.RetrieveAppsByUserNameDataKey);
public static IEnumerable<string> RetrievesByUserName(string userName) => CacheManager.GetOrAdd($"{DbHelper.RetrieveAppsByUserNameDataKey}-{userName}", key => DbContextManager.Create<App>().RetrievesByUserName(userName), RetrieveAppsByUserNameDataKey);
}
}

View File

@ -0,0 +1,87 @@
using Bootstrap.Security;
using Longbow.Configuration;
using Longbow.OAuth;
using Longbow.Security.Cryptography;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
namespace Bootstrap.DataAccess
{
/// <summary>
/// Gitee 授权帮助类
/// </summary>
public static class OAuthHelper
{
private static readonly ConcurrentDictionary<string, OAuthUser> _pool = new ConcurrentDictionary<string, OAuthUser>();
/// <summary>
/// 设置 GiteeOptions.Events.OnCreatingTicket 方法
/// </summary>
/// <param name="option"></param>
public static void Configure<TOptions>(TOptions option) where TOptions : LgbOAuthOptions
{
option.Events.OnCreatingTicket = async context =>
{
var user = context.User.ToObject<OAuthUser>();
user.Schema = context.Scheme.Name;
_pool.AddOrUpdate(user.Login, userName => user, (userName, u) => { u = user; return user; });
// call webhook
var config = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();
var webhookUrl = config.GetValue($"{option.GetType().Name}:StarredUrl", "");
if (!string.IsNullOrEmpty(webhookUrl))
{
var webhookParameters = new Dictionary<string, string>()
{
{ "access_token", context.AccessToken }
};
var url = QueryHelpers.AddQueryString(webhookUrl, webhookParameters);
var requestMessage = new HttpRequestMessage(HttpMethod.Put, url);
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
await context.Backchannel.SendAsync(requestMessage, context.HttpContext.RequestAborted);
}
};
}
/// <summary>
/// 插入 Gitee 授权用户到数据库中
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public static BootstrapUser RetrieveUserByUserName<TOptions>(string userName) where TOptions : LgbOAuthOptions
{
User ret = null;
var user = _pool.TryGetValue(userName, out var giteeUser) ? giteeUser : null;
if (user != null)
{
var option = ConfigurationManager.Get<TOptions>();
ret = new User()
{
ApprovedBy = "OAuth",
ApprovedTime = DateTime.Now,
DisplayName = user.Name,
UserName = user.Login,
Password = LgbCryptography.GenerateSalt(),
Icon = user.Avatar_Url,
Description = $"{user.Schema}({user.Id})",
App = option.App
};
DbContextManager.Create<User>().Save(ret);
CacheCleanUtility.ClearCache(cacheKey: UserHelper.RetrieveUsersDataKey);
// 根据配置文件设置默认角色
var usr = UserHelper.Retrieves().First(u => u.UserName == userName);
var roles = RoleHelper.Retrieves().Where(r => option.Roles.Any(rl => rl.Equals(r.RoleName, StringComparison.OrdinalIgnoreCase))).Select(r => r.Id);
RoleHelper.SaveByUserId(usr.Id, roles);
}
return ret;
}
}
}

View File

@ -22,7 +22,7 @@ namespace Bootstrap.DataAccess
{
if (context.User.Identity.IsAuthenticated)
{
var user = UserHelper.RetrieveUserByUserName(context.User.Identity.Name);
var user = UserHelper.RetrieveUserByUserName(context.User.Identity);
// user == null 以前登录过客户端保留了 Cookie 但是用户名可能被系统删除
// link bug: https://gitee.com/LongbowEnterprise/BootstrapAdmin/issues/I123MH

View File

@ -1,9 +1,12 @@
using Bootstrap.Security;
using Bootstrap.Security.DataAccess;
using Longbow.Cache;
using Longbow.GiteeAuth;
using Longbow.GitHubAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Text.RegularExpressions;
namespace Bootstrap.DataAccess
@ -95,7 +98,7 @@ namespace Bootstrap.DataAccess
value = value.Where(v => !admins.Any(u => u.Id == v));
if (!value.Any()) return true;
var ret = DbContextManager.Create<User>().Delete(value);
if (ret) CacheCleanUtility.ClearCache(userIds: value);
if (ret) CacheCleanUtility.ClearCache(userIds: value, cacheKey: RetrieveUsersByNameDataKey + "*");
return ret;
}
@ -307,9 +310,30 @@ namespace Bootstrap.DataAccess
/// <summary>
/// 通过登录名获取登录用户方法
/// </summary>
/// <param name="userName"></param>
/// <param name="identity"></param>
/// <returns></returns>
public static BootstrapUser RetrieveUserByUserName(string userName) => CacheManager.GetOrAdd(string.Format("{0}-{1}", RetrieveUsersByNameDataKey, userName), k => DbContextManager.Create<User>()?.RetrieveUserByUserName(userName), RetrieveUsersByNameDataKey);
public static BootstrapUser RetrieveUserByUserName(IIdentity identity) => CacheManager.GetOrAdd(string.Format("{0}-{1}", RetrieveUsersByNameDataKey, identity.Name), k =>
{
var userName = identity.Name;
var proxyList = new List<Func<string, BootstrapUser>>();
// 本地数据库认证
proxyList.Add(DbContextManager.Create<User>().RetrieveUserByUserName);
// Gitee 认证
if (identity.AuthenticationType == GiteeDefaults.AuthenticationScheme) proxyList.Add(OAuthHelper.RetrieveUserByUserName<GiteeOptions>);
// GitHub 认证
if (identity.AuthenticationType == GitHubDefaults.AuthenticationScheme) proxyList.Add(OAuthHelper.RetrieveUserByUserName<GitHubOptions>);
BootstrapUser user = null;
foreach (var p in proxyList)
{
user = p.Invoke(userName);
if (user != null) break;
}
return user;
}, RetrieveUsersByNameDataKey);
/// <summary>
/// 通过登录账号获得用户信息

View File

@ -204,12 +204,12 @@ namespace Bootstrap.DataAccess
/// <returns></returns>
public virtual bool Save(User user)
{
var ret = false;
user.PassSalt = LgbCryptography.GenerateSalt();
user.Password = LgbCryptography.ComputeHash(user.Password, user.PassSalt);
user.RegisterTime = DateTime.Now;
var db = DbManager.Create();
bool ret;
try
{
db.BeginTransaction();

View File

@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.16" />
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.17" />
<PackageReference Include="Longbow.Configuration" Version="2.2.7" />
<PackageReference Include="Longbow.Logging" Version="2.2.13" />
<PackageReference Include="Microsoft.AspNetCore.App" />

View File

@ -33,7 +33,7 @@ namespace Bootstrap.Client.Models
// set Icon
var icon = $"/{DictHelper.RetrieveIconFolderPath().Trim('~', '/')}/{user.Icon}";
Icon = string.IsNullOrEmpty(ConfigurationManager.GetValue("SimulateUserName", string.Empty)) ? $"{authHost.TrimEnd('/')}{icon}" : "/images/admin.jpg";
Icon = user.Icon.Contains("://", StringComparison.OrdinalIgnoreCase) ? user.Icon : (string.IsNullOrEmpty(ConfigurationManager.GetValue("SimulateUserName", string.Empty)) ? $"{authHost.TrimEnd('/')}{icon}" : "/images/admin.jpg");
if (!string.IsNullOrEmpty(user.Css)) Theme = user.Css;
}

View File

@ -1,8 +1,6 @@
using Bootstrap.Client.DataAccess;
using Longbow.Configuration;
using Longbow.Web;
using Longbow.Web.SignalR;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
@ -13,7 +11,6 @@ using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Linq;
namespace Bootstrap.Client
{

View File

@ -10,8 +10,14 @@
<script src="~/js/index.js"></script>
}
<p>这是开源后台管理框架前台系统首页,欢迎使用</p>
<p>点击右上角登录信息下拉菜单中的设置按钮进入 <b>后台管理</b> 或者 <b><a href="@Model.SettingsUrl">直接进入</a></b></p>
<p class="text-danger"><b>由于本系统为演示系统,内部对一些敏感操作进行了限制操作,如一些特殊用户不能删除</b></p>
<p>点击右上角进入 <b>后台管理</b> 或者 <b><a href="@Model.SettingsUrl">直接进入</a></b></p>
<p>系统密码</p>
<p>
<ol>
<li>管理账号 Admin/123789</li>
<li>普通账号 User/123789</li>
</ol>
</p>
<p>最新功能更新请查看 <b><a href="https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97?sort_id=1585945">更新日志</a></b></p>
<p>
<button id="btnCaptcha" class="btn btn-success ml-2 ml-md-0"><i class="fa fa-send-o"></i><span>点击我出现行为验证码</span></button>

View File

@ -1,6 +1,6 @@
@model ModelBase
<footer class="position-fixed">
<div><span id="websiteFooter">@Model.Footer</span></div>
<div><span id="websiteFooter">@Model.Footer (演示系统)</span></div>
<a id="gotoTop" href="#" class="go-top" title="返回顶部" data-toggle="tooltip" data-placement="left">
<i class="fa fa-angle-up"></i>
</a>

View File

@ -1,6 +1,7 @@
using Longbow.Web.Mvc;
using System;
using System.Linq;
using System.Security.Principal;
using Xunit;
namespace Bootstrap.DataAccess.SqlServer
@ -134,7 +135,7 @@ namespace Bootstrap.DataAccess.SqlServer
[Fact]
public void RetrieveUserByUserName_Ok()
{
var usr = UserHelper.RetrieveUserByUserName("Admin");
var usr = UserHelper.RetrieveUserByUserName(new GenericIdentity("Admin"));
Assert.Equal("Administrator", usr.DisplayName);
}