You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
13 KiB
279 lines
13 KiB
using Application.Domain.Entities;
|
|
using IdentityModel;
|
|
using IdentityServer4;
|
|
using IdentityServer4.Models;
|
|
using Infrastructure.Data;
|
|
using Infrastructure.Domain;
|
|
using Infrastructure.Email;
|
|
using Infrastructure.Extensions;
|
|
using Infrastructure.Security;
|
|
using Infrastructure.Sms;
|
|
using Infrastructure.Web;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace UserCenter
|
|
{
|
|
public class Startup : BaseStartup
|
|
{
|
|
public Startup(IConfiguration configuration, IHostingEnvironment env) : base(configuration, env)
|
|
{
|
|
}
|
|
|
|
public override void ConfigureServices(IServiceCollection services)
|
|
{
|
|
base.ConfigureServices(services);
|
|
services.AddTransient<IEmailSender, EmptyEmailSender>();
|
|
services.AddTransient<ISmsSender, EmptySmsSender>();
|
|
}
|
|
|
|
public override void AddAuthentication(IServiceCollection services)
|
|
{
|
|
services.AddIdentityServer()
|
|
.AddDeveloperSigningCredential()
|
|
.AddInMemoryIdentityResources(new IdentityResource[] {
|
|
new IdentityResources.OpenId(),
|
|
new IdentityResources.Profile()
|
|
})
|
|
.AddInMemoryApiResources(new ApiResource[] { new ApiResource("api1", "My API") })
|
|
.AddInMemoryClients(new IdentityServer4.Models.Client[] {
|
|
new IdentityServer4.Models.Client
|
|
{
|
|
ClientId="mvc",
|
|
ClientName="物联网平台",
|
|
AllowedGrantTypes = GrantTypes.Implicit,
|
|
RequireConsent=false,
|
|
RedirectUris = { "http://localhost:8082/signin-oidc" },
|
|
PostLogoutRedirectUris = { "http://localhost:8082/signout-callback-oidc" },
|
|
|
|
AllowedScopes = new List<string>
|
|
{
|
|
IdentityServerConstants.StandardScopes.OpenId,
|
|
IdentityServerConstants.StandardScopes.Profile
|
|
}
|
|
}
|
|
})
|
|
.AddResourceOwnerValidator<ResourceOwnerValidator>()
|
|
//.AddProfileService<ProfileService>()
|
|
;
|
|
services.AddAuthentication(o =>
|
|
{
|
|
o.DefaultAuthenticateScheme = IdentityServerConstants.DefaultCookieAuthenticationScheme;
|
|
o.DefaultSignOutScheme = IdentityServerConstants.SignoutScheme;
|
|
})
|
|
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o =>
|
|
{
|
|
o.TokenValidationParameters = new TokenValidationParameters
|
|
{
|
|
NameClaimType = JwtClaimTypes.Name,
|
|
RoleClaimType = JwtClaimTypes.Role,
|
|
ValidIssuer = "server",
|
|
ValidAudience = "client",
|
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(this._cfg["jwt:key"]))
|
|
};
|
|
o.Events = new JwtBearerEvents()
|
|
{
|
|
OnChallenge = context =>
|
|
{
|
|
//context.Token = context.Request.Query["access_token"];
|
|
return Task.CompletedTask;
|
|
},
|
|
OnAuthenticationFailed = context =>
|
|
{
|
|
//context.Token = context.Request.Query["access_token"];
|
|
return Task.CompletedTask;
|
|
},
|
|
OnTokenValidated = context =>
|
|
{
|
|
//context.Token = context.Request.Query["access_token"];
|
|
return Task.CompletedTask;
|
|
},
|
|
OnMessageReceived = context =>
|
|
{
|
|
//context.Token = context.Request.Query["access_token"];
|
|
return Task.CompletedTask;
|
|
}
|
|
};
|
|
});
|
|
//services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
|
// .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, opts =>
|
|
// {
|
|
// opts.Cookie.Name = this.GetType().FullName;
|
|
// opts.LoginPath = "/Account/Login";
|
|
// opts.LogoutPath = "/Account/Logout";
|
|
// opts.AccessDeniedPath = "/Account/AccessDenied";
|
|
// //不配置SessionStore则存储到cookie
|
|
// var useCookieSessionStore = this._cfg.GetSection("AppSettings").GetValue<bool>("UseCookieSessionStore");
|
|
// if (!useCookieSessionStore)
|
|
// {
|
|
// opts.SessionStore = services.BuildServiceProvider().GetService<ITicketStore>();
|
|
// }
|
|
// opts.Events = new CookieAuthenticationEvents
|
|
// {
|
|
// //OnRedirectToLogin = RedirectToLogin(),
|
|
// OnValidatePrincipal = ValidatePrincipal
|
|
// };
|
|
// })
|
|
// .AddGitHub(options =>
|
|
// {
|
|
// options.ClientId = "6ec6712a4dbbe3f1f1ac";
|
|
// options.ClientSecret = "ea91f08553a3b242340a905fb000d5a828d9a69e";
|
|
// })
|
|
//.AddQQ(o =>
|
|
//{
|
|
// //https://connect.qq.com/manage.html
|
|
// o.ClientId = "101569040";
|
|
// o.ClientSecret = "5541d994fe8f3b3fa428c63a47139b39";
|
|
//});
|
|
}
|
|
|
|
public override void UseAuthentication(IApplicationBuilder app)
|
|
{
|
|
app.UseIdentityServer();
|
|
}
|
|
|
|
public override Task ValidatePrincipal(CookieValidatePrincipalContext arg)
|
|
{
|
|
return Task.Run(() =>
|
|
{
|
|
var userRepo = arg.HttpContext.RequestServices.GetService<IRepository<User>>();
|
|
|
|
var userName = arg.Principal.Identity.Name;
|
|
var userPermissions = userRepo.ReadOnlyTable().Where(o => o.UserName == userName)
|
|
.SelectMany(o => o.UserRoles)
|
|
.Select(o => o.Role)
|
|
.SelectMany(o => o.RolePermissions)
|
|
.Select(o => o.Permission.Number)
|
|
.ToList();
|
|
var currentPermissions = arg.Principal.Claims.Where(o => o.Type == "Role").Select(o => o.Value).ToList();
|
|
if (!currentPermissions.SequenceEqual(userPermissions))
|
|
{
|
|
arg.HttpContext.SignOutAsync();
|
|
arg.HttpContext.SignIn(userName, userPermissions, arg.Properties.IsPersistent);
|
|
}
|
|
});
|
|
}
|
|
|
|
public override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
modelBuilder.Entity<PermissionCategory>().HasOne(o => o.Parent).WithMany(o => o.Children).HasForeignKey(o => o.ParentId).OnDelete(DeleteBehavior.SetNull);
|
|
modelBuilder.Entity<Permission>().HasOne(o => o.Category).WithMany(o => o.Permissions).HasForeignKey(o => o.CategoryId).OnDelete(DeleteBehavior.SetNull);
|
|
modelBuilder.Entity<UserRole>().HasOne(o => o.User).WithMany(o => o.UserRoles).HasForeignKey(o => o.UserId);
|
|
modelBuilder.Entity<UserRole>().HasOne(o => o.Role).WithMany(o => o.UserRoles).HasForeignKey(o => o.RoleId);
|
|
modelBuilder.Entity<RolePermission>().HasOne(o => o.Role).WithMany(o => o.RolePermissions).HasForeignKey(o => o.RoleId);
|
|
modelBuilder.Entity<RolePermission>().HasOne(o => o.Permission).WithMany(o => o.RolePermissions).HasForeignKey(o => o.PermissionId);
|
|
modelBuilder.Entity<User>().HasIndex(o => o.PhoneNumber).IsUnique();
|
|
modelBuilder.Entity<User>().HasIndex(o => o.NickName).IsUnique(); modelBuilder.Entity<Role>().HasIndex(o => o.Name).IsUnique();
|
|
modelBuilder.Entity<PermissionCategory>().HasIndex(o => o.Number).IsUnique();
|
|
modelBuilder.Entity<Permission>().HasIndex(o => o.Number).IsUnique();
|
|
modelBuilder.Entity<UserRole>().HasIndex(o => new { o.UserId, o.RoleId }).IsUnique();
|
|
modelBuilder.Entity<RolePermission>().HasIndex(o => new { o.RoleId, o.PermissionId }).IsUnique();
|
|
//关系
|
|
modelBuilder.Entity<Site>();
|
|
modelBuilder.Entity<Site>().HasIndex(o => o.Name).IsUnique();
|
|
//identity
|
|
//modelBuilder.Entity<Client>().HasIndex(o => o.ClientId).IsUnique();
|
|
}
|
|
|
|
public override void Seed(DbContext dbContext, IServiceProvider serviceProvider, IConfiguration configuration)
|
|
{
|
|
dbContext.Set<PermissionCategory>().Add(new PermissionCategory
|
|
{
|
|
Name = "配置",
|
|
Number = "Configuration",
|
|
Permissions = new List<Permission> {
|
|
new Permission { Name = "查询配置", Number = "ListConfiguration",DisplayOrder =1 },
|
|
new Permission { Name = "修改配置", Number = "EditConfiguration",DisplayOrder =2 }
|
|
}
|
|
});
|
|
int i = 1;
|
|
var skipReadCollection = new string[] { "Permission" };
|
|
var skipAddCollection = new string[] { "Permission" };
|
|
foreach (var item in dbContext.Model.GetEntityTypes())
|
|
{
|
|
var type = item.ClrType;
|
|
var name = type.GetDisplayName();
|
|
var number = type.Name;
|
|
var category = new PermissionCategory
|
|
{
|
|
Name = name,
|
|
Number = type.Name,
|
|
DisplayOrder = i
|
|
};
|
|
category.Permissions.Add(new Permission { Name = $"查询{name}", Number = $"List{number}", DisplayOrder = 10 * i + 1 });
|
|
if (!skipReadCollection.Contains(type.Name))
|
|
{
|
|
category.Permissions.Add(new Permission { Name = $"查看{name}", Number = $"Read{number}", DisplayOrder = 10 * i + 2 });
|
|
}
|
|
if (!skipAddCollection.Contains(type.Name))
|
|
{
|
|
category.Permissions.Add(new Permission { Name = $"添加{name}", Number = $"Add{number}", DisplayOrder = 10 * i + 3 });
|
|
}
|
|
if (!typeof(IDisableUpdate).IsAssignableFrom(type))
|
|
{
|
|
category.Permissions.Add(new Permission { Name = $"修改{name}", Number = $"Edit{number}", DisplayOrder = 10 * i + 4 });
|
|
}
|
|
if (!typeof(IDisableDelete).IsAssignableFrom(type))
|
|
{
|
|
category.Permissions.Add(new Permission { Name = $"删除{name}", Number = $"Delete{number}", DisplayOrder = 10 * i + 5 });
|
|
}
|
|
dbContext.Set<PermissionCategory>().Add(category);
|
|
i += 1;
|
|
}
|
|
dbContext.SaveChanges();
|
|
|
|
var adminRole = new Role { Name = "管理员", IsReadOnly = true };
|
|
foreach (var item in dbContext.Set<Permission>())
|
|
{
|
|
adminRole.RolePermissions.Add(new RolePermission { Permission = item, IsReadOnly = true });
|
|
}
|
|
var encryptionService = serviceProvider.GetService<IEncryptionService>();
|
|
var securityStam = "123456";
|
|
dbContext.Set<User>().Add(new User
|
|
{
|
|
UserName = "admin",
|
|
SecurityStamp = securityStam,
|
|
PasswordHash = encryptionService.CreatePasswordHash("123456", securityStam),
|
|
PasswordConfirmed = true,
|
|
Email = "test@test.com",
|
|
EmailConfirmed = true,
|
|
PhoneNumber = "13000000000",
|
|
PhoneNumberConfirmed = true,
|
|
UserRoles = new List<UserRole> { new UserRole { Role = adminRole } }
|
|
});
|
|
dbContext.SaveChanges();
|
|
var host = Helper.Instance.GetLocalIP().ToString();
|
|
dbContext.Set<Site>().Add(new Site
|
|
{
|
|
Name = "物联网平台",
|
|
Description = "智能设备管控中心",
|
|
Home = $"http://{host}:8001/",
|
|
Login = $"http://{host}:8001/Account/JsonpLogin",
|
|
Logout = $"http://{host}:8001/Account/JsonpLogout",
|
|
Key = "123456"
|
|
});
|
|
dbContext.Set<Site>().Add(new Site
|
|
{
|
|
Name = "学习平台",
|
|
Description = "资源库、在线学习、网络课程中心",
|
|
Home = $"http://{host}:8082/",
|
|
Login = $"http://{host}:8082/Account/JsonpLogin",
|
|
Logout = $"http://{host}:8082/Account/JsonpLogout",
|
|
Key = "123456"
|
|
});
|
|
dbContext.SaveChanges();
|
|
}
|
|
}
|
|
} |