隐许可SPA
问题描述:
如何限制与交付式在特定的SPA客户机的每个客户端应用程序登录的x量 - 隐式隐许可SPA
This is out of scope within Identity server
解试图 -
访问令牌持久存储到数据库,但是这种方法客户端不更新访问令牌而没有进入代码,因为客户端浏览器请求带有有效令牌,尽管它已过期无提示认证正在通过更新令牌发出一个新的参考标记(可以在表persistgrants token_type'reference_token'中看到)
Cookie事件 - 关于validateAsync - 虽然这只适用于服务器web,但我们不能将这个逻辑放在SPA客户端的oidc库。
自定义signInManager通过重写SignInAsync - 但执行没有到达调试模式的这一点,因为IDM一直认识到用户有一个有效的托克(虽然已过期)不断发出令牌(请注意,没有刷新令牌这里通过存储和修改管理它!!!)
任何线索如何IDM重的问题没有考虑用户的登录屏幕的道理,即使访问令牌过期??(Silent authentication? ?
答
实现配置文件服务覆盖activeasync
public override async Task IsActiveAsync(IsActiveContext context)
{
var sub = context.Subject.GetSubjectId();
var user = await userManager.FindByIdAsync(sub);
//Check existing sessions
if (context.Caller.Equals("AccessTokenValidation", StringComparison.OrdinalIgnoreCase))
{
if (user != null)
context.IsActive = !appuser.VerifyRenewToken(sub, context.Client.ClientId);
else
context.IsActive = false;
}
else
context.IsActive = user != null;
}
启动
services.AddTransient<IProfileService, ProfileService>();
,同时在配置服务
.AddProfileService<ProfileService>();
更新
Session.Abandon(); //is only in aspnet prior versions not in core
Session.Clear();//clears the session doesn't mean that session expired this should be controlled by addSession life time when including service.
我添加身份服务器的服务集合碰巧找到了一种更好的方法,即使用aspnetuser securitystamp,每次用户登录时都要更新安全标记,以便任何之前的活动会话/ cookie都会失效。
_userManager.UpdateSecurityStampAsync(_userManager.FindByEmailAsync(model.Email).Result).Result
更新(最终):
在登入: -
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberLogin, false);
if (result.Succeeded)
{
//Update security stamp to invalidate existing sessions
var user = _userManager.FindByEmailAsync(model.Email).Result;
var test= _userManager.UpdateSecurityStampAsync(user).Result;
//Refresh the cookie to update securitystamp on authenticationmanager responsegrant to the current request
await _signInManager.RefreshSignInAsync(user);
}
档案服务实现: -
public class ProfileService : ProfileService<ApplicationUser>
{
public override async Task IsActiveAsync(IsActiveContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (context.Subject == null) throw new ArgumentNullException(nameof(context.Subject));
context.IsActive = false;
var subject = context.Subject;
var user = await userManager.FindByIdAsync(context.Subject.GetSubjectId());
if (user != null)
{
var security_stamp_changed = false;
if (userManager.SupportsUserSecurityStamp)
{
var security_stamp = (
from claim in subject.Claims
where claim.Type =="AspNet.Identity.SecurityStamp"
select claim.Value
).SingleOrDefault();
if (security_stamp != null)
{
var latest_security_stamp = await userManager.GetSecurityStampAsync(user);
security_stamp_changed = security_stamp != latest_security_stamp;
}
}
context.IsActive =
!security_stamp_changed &&
!await userManager.IsLockedOutAsync(user);
}
}
}
*
挂钩的服务集合中: -
*
services.AddIdentityServer()
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<ProfileService>();
即在每次登录时,用户的安全戳更新,并且推送到cookie,当令牌到期时,授权端点将会验证安全性变化,如果有,则重定向用户登录。这样我们确保只有一个活动会话