0

如何限制与交付式在特定的SPA客户机的每个客户端应用程序登录的x量 - 隐式隐许可SPA

This is out of scope within Identity server

解试图 -

  1. 访问令牌持久存储到数据库,但是这种方法客户端不更新访问令牌而没有进入代码,因为客户端浏览器请求带有有效令牌,尽管它已过期无提示认证正在通过更新令牌发出一个新的参考标记(可以在表persistgrants token_type'reference_token'中看到)

  2. Cookie事件 - 关于validateAsync - 虽然这只适用于服务器web,但我们不能将这个逻辑放在SPA客户端的oidc库。

  3. 自定义signInManager通过重写SignInAsync - 但执行没有到达调试模式的这一点,因为IDM一直认识到用户有一个有效的托克(虽然已过期)不断发出令牌(请注意,没有刷新令牌这里通过存储和修改管理它!!!)

任何线索如何IDM重的问题没有考虑用户的登录屏幕的道理,即使访问令牌过期??(Silent authentication? ?

回答

0

实现配置文件服务覆盖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,当令牌到期时,授权端点将会验证安全性变化,如果有,则重定向用户登录。这样我们确保只有一个活动会话