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.
iot/projects/UserCenter/Startup.cs

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();
}
}
}