- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如何防止一个用户 ID 一次只能登录一台计算机?例如,用户“Sam”登录到他的桌面。用户“Sam”也从他们的笔记本电脑登录。现在我需要终止桌面上的 session ,或者我想要发生的是使旧 token 在桌面上无效。
我正在使用 dotnet 5.0
您是否需要在数据库的“用户”表中使用名为 currentlyloggedinUser 的列来查看他们是否已使用 bool 值登录?
您还需要安全印章吗?
下面是放在AuthController中的登录方法
[AllowAnonymous]
[HttpPost("login")]
public async Task<IActionResult> Login(UserForLoginDto userForLoginDto)
{
try
{
// does the user exist in the database
var user = await _userManager.FindByNameAsync(userForLoginDto.Username);
// does the password match
var result = await _signInManager.CheckPasswordSignInAsync(user, userForLoginDto.Password, true);
//if the users are logged in, store True Value in the database
user.nonconcurrent = true;
var noLoggedin = await _userManager.UpdateAsync(user);
if(!result.IsLockedOut)
{
if(user.IsEnabled)
{
if (result.Succeeded)
{
var userToReturn = _mapper.Map<UserForReturnDto>(user);
return Ok(new
{
token = GenerateJwtToken(user).Result,
user = userToReturn,
});
}
return Unauthorized("Login Failed"); //if username and password are incorrect return unauthorised
}
return Unauthorized("This account is disabled. Please get an administrator to unlock this account.");
}
return Unauthorized("This account is locked out. Please try again in 10 minutes or get an " +
"administrator to unlock your account.");
}
catch (ArgumentNullException)
{
return Unauthorized("Login Failed");
}
}
下面是StartUp.cs的一部分
namespace Schedular.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// services.AddDbContext<DataContext>(x => x.UseMySql(Configuration
// .GetConnectionString("DefaultConnection")));
services.AddDbContext<DataContext>(x => x.UseMySql(Configuration
.GetConnectionString("DefaultConnection"),
new MySqlServerVersion(new Version(8, 0, 21)),
mySqlOptions => mySqlOptions
.CharSetBehavior(CharSetBehavior.NeverAppend)));
var lockoutOptions = new LockoutOptions()
{
AllowedForNewUsers = true,
DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10),
MaxFailedAccessAttempts = 5
};
// for role and identity authentication
// initial creation of user in the user table in database
IdentityBuilder builder = services.AddIdentityCore<User>(opt =>
{
// password requirements
opt.Lockout = lockoutOptions;
opt.Password.RequireDigit = true;
opt.Password.RequiredLength = 8;
opt.Password.RequireNonAlphanumeric = false;
opt.Password.RequireUppercase = true;
});
builder = new IdentityBuilder(builder.UserType, typeof(Role), builder.Services);
builder.AddEntityFrameworkStores<DataContext>();
builder.AddRoleValidator<RoleValidator<Role>>();
builder.AddRoleManager<RoleManager<Role>>();
builder.AddSignInManager<SignInManager<User>>();
// allows api to use authentication
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
};
});
// authorisation policy
services.AddAuthorization(options =>
{
options.AddPolicy("AdminAccess", policy => policy.RequireRole("Admin"));
options.AddPolicy("everyone", policy => policy.RequireRole("Admin", "standard"));
});
services.AddControllers(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
.AddNewtonsoftJson(opt =>
{
opt.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.AddScoped<ITaskScheduleRepository, TaskScheduleRepository>();
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<INotesRepository, NotesRepository>();
services.AddScoped<IAttachmentFileRepository, AttachmentFileRepository>();
services.AddScoped<ICustomerRepository, CustomerRepository>();
services.AddScoped<IReportRepository, ReportRepository>();
services.AddControllers();
services.AddCors();
//allows use of tokens
// Auto Mapper Configurations
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new AutoMapperProfiles());
});
IMapper mapper = mappingConfig.CreateMapper();
services.AddSingleton(mapper);
}
这是user.cs模型文件
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Identity;
namespace Schedular.API.Models
{
public class User: IdentityUser<int>
{
public string FirstName { get; set; }
public string LastName { get; set; }
// to disable account and have a time limiter on when it can be enabled again
public bool nonconcurrent { get; set; }
// connect User table to the userRole join table. the below configure the relationship
public virtual ICollection<UserRole> UserRoles {get; set;}
}
}
下面是userForLoginDto
namespace Schedular.API.Dtos
{
public class UserForLoginDto
{
public string Username { get; set; }
public string Password { get; set; }
}
}
最佳答案
您可以通过多种方式实现这一目标。作为一个简单的起点,我将提供两种可能性。
首先可能是在您的数据(数据库、缓存、 token 等)中包含用户的 IP 地址。然后您可以验证是否正在使用第一个登录的 IP 地址,并阻止所有其他登录尝试或来自给定用户的任何其他 IP 的后续请求。
一个简单的方法如下所示:
public class UserForLoginDto
{
public string Username { get; set; }
public string Password { get; set; }
public string CurrentIpAddress { get; set; }
}
然后您可以从请求 或http 上下文 中提取 IP 并比较以验证登录,如下所示:
if(HttpContext.Connection.RemoteIpAddress == userForLoginDto.CurrentIpAddress)
{
// do things here after validation.
}
else
{
// kick-out invalid login attempt.
}
最后,您需要在用户结束 session 、因不活动而被踢出等时清除该 IP 值。因此,如果下一次登录是在不同的设备上,则可以更改 IP 地址。不是一个完美的解决方案,而是一个从简单开始的好方法。
这有利于概念验证,但不一定适合生产,因为您可能会遇到 IP 并不总是唯一的问题。
其次您可以生成一个 GUID、UUID 或其他某种唯一的数据,而不是 IP 地址,它并不总是唯一的通过 token 和持久化数据,即在数据库中。
public class UserForLoginDto
{
public string Username { get; set; }
public string Password { get; set; }
public Guid CurrentLogin { get; set; }
}
然后继续在登录时进行与之前相同的检查:
if(Request.Headers.GetValues("your-token-here").FirstOrDefault() == userForLoginDto.CurrentLogin)
{
// do things here after validation.
}
else
{
// kick-out invalid login attempt.
}
所以这与第一个示例非常相似,但现在您有一个最有可能的唯一数据点来检查是否有更安全假设的请求。只需清除 session 结束时以及您在服务器端持久保存 token 数据的 token 数据,以便您可以在下次成功登录时重置它。
您还需要在每次成功登录时创建一个新的唯一数据点,如果已经存在一个数据点,您可以结束上一个 session 或使登录尝试无效,以帮助防止同时使用多个设备。
尝试研究 JWT(Json Web token )以寻找基于 token 的方法。那里有很多很好的例子和教程,如 JWT Authentication with C#或 creating and validating jwt tokens in asp net core .
同样,有很多方法可以实现像这样的复杂事物。所以尝试几种不同的方法,看看你喜欢什么,以及什么最适合你和你的项目或工作。就我个人而言,我建议研究基于 token 的身份验证和授权,这样您就可以更轻松地检查每个请求,但随着您深入研究,选择最适合您的场景的方法。
关于c# - 如何防止用户登录多个设备以及如何从之前的设备结束 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65117958/
iphone设备UDID、iphone设备ID和iphone设备Token之间有什么区别? 通常,当我们使用苹果推送通知服务时,会使用 iPhone 设备 token 。 但我的目标只是识别唯一的 i
我们使用 firebase 从服务器向 Android 和 IOS 设备发送通知,并且我们使用旧版 FCM 发送通知。但是当我们的应用程序在后台时,通知由系统本身处理,因此我们无法通过应用程序处理它。
在 Google 上搜索后,我发现人们说只能通过“MFi 程序”将 iOS 设备与非 iOS 设备连接起来。这是真的吗? 我的项目主要集中于直接通过蓝牙与Arduino设备发送和接收信息。 iOS和非
所以我有一个通用应用程序,我正在设置 UIScrollView 的内容大小。显然,iPhone 和 iPad 上的内容大小会有所不同。如何为 iPad 设置某种尺寸,为 iPhone 和 iPod t
问题:如何在 pod 中使用连接到主机的原始设备作为 block 设备。 我尝试使用类型为“BlockDevice”的“hostPath” volumes: - my-data: hostPath
Implemented GCKDeviceScannerListener Singleton Class on ViewController, however its delegate methods
我有一个 (PhoneGap) 应用程序,它将成功获得 Passbook 通行证,并且还将成功接收与 Passbook 分开的推送通知(当伪造设备 ID 时)。 我遇到的问题是发送给注册设备的设备 I
我正在尝试找到一种方法,通过我目前正在使用的 iOS 应用程序访问我的信标的电池电量。我正在使用 Kontakt 的 iBeacon 设备。我浏览了 Estimote iOS SDK,他们提供了一种实
我正在努力让 CUDA 应用程序也能监控 GPU 的核心温度。可通过 NVAPI 访问该信息。 问题是我想确保在运行代码时监控的是同一个 GPU。 但是,似乎有信息表明我从 NvAPI_EnumPhy
从沙箱模式到生产模式,设备 token 有何不同? 我认为我已将一些设备 token 锁定为生产模式,并且无法将它们从开发中插入。 关于如何检查有什么想法吗? 最佳答案 当您使用开发证书构建应用程序时
目录 /run/user/1000/gvfs 和 ~/.gvfs 分别是空的和不存在的。我的图形文件管理器 (Thunar) 能够检测和访问设备的内部和外部存储器。 命令 gvfs-mount -l
我有一个 Android 平板电脑,它有一个迷你 USB 端口和一个 USB 端口,我想编写一个与 USB key 通信的应用程序。我写了一个demo来找出U盘,但是没有任何反应。 令我不安的是,如果
我们将 PHP 版本从 5.4.25 更改为 5.4.45,并在服务器上安装了 MS SQL 驱动程序。在更改服务器之前,一切正常,但在更改服务器之后,我遇到了 Web 服务问题。我们的身份验证 So
我想知道是否有人使用此 API 在 Android 设备上同时从 2 个后置摄像头捕获图像或视频:https://source.android.com/docs/core/camera/concurr
我正在为客户构建一个物联网解决方案,网络管理员坚持要求设备仅通过访客网络进行连接,该网络有一个强制门户,其中的服务条款必须通过按下 UI 按钮来接受,然后才能获得外部互联网访问。到目前为止,我见过的大
我无法弄清楚这里的格式规则..在我的示例中,代码行太多,无法为每行添加 4 个空格,因此这里是我需要帮助的代码的链接 http://nitemsg.blogspot.com/2011/01/heres
如果我在我的设备上接受推送通知,并且不保存设备 token ,那么我如何在自定义 View 中查看设备 token 或恢复警报 View ? 我删除了应用程序并重新安装,但看不到设备 token 警报
我试图找出在尝试并行比较和复制设备 block 与 pthreads 时我做错了什么。看起来我正在脱离同步并且比较阶段无法正常工作。任何帮助将不胜感激 #ifndef __dbg_h__ #defin
我刚刚写完所有这些内容,但这个红色的小栏告诉我我不能发布图片或两个以上的链接。因此,如果您可以引用 this Imgur album , 那简直太好了。谢谢。 我在这里相对较新,甚至对 android
我需要启用 mysql 常规日志并将其通过 nsf 移动到我系统中的另一个驱动器/设备! 所以,我在 my.cnf 中启用了它: general_log = 1 general_log_fi
我是一名优秀的程序员,十分优秀!