本文介绍了身份服务器隐式授予SPA4并发登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何通过授予类型-隐式

how to restrict x amount of login on each client app in specific the SPA client with grant type - implicit

尝试过的解决方案-


  1. 访问令牌仍保留在数据库中,但是这种方法客户端不断更新访问令牌而不用编写代码,因为客户端浏览器请求是随同的有效令牌,尽管它已过期,但静默身份验证通过发出新的参考令牌来更新令牌(可以在表persistGrants token_type'reference_token'中看到)

  1. Access tokens persisted to DB, however this approach the client kept updating the access token without coming to code because the client browser request is coming with a valid token though its expired the silent authentication is renewing the token by issues a new reference token ( that can be seen in the table persistGrants token_type 'reference_token')

Cookie事件-在validateAsync上-运气不好,尽管这仅适用于服务器网络,但是我们不能将此逻辑放在SPA客户端的oidc库中。

Cookie event - on validateAsync - not much luck though this only works for the server web, we can't put this logic on the oidc library on the client side for SPA's.

自定义signInManager通过覆盖SignInAsync-但执行未达到此范围指向调试模式,因为IDM一直在识别用户有有效的令牌(尽管已过期),并且一直在重新发布令牌(请注意,这里没有刷新令牌可以通过存储和修改来管理它!)

Custom signInManager by overriding SignInAsync - but the the executing is not reaching to this point in debug mode because the IDM kept recognising the user has a valid toke ( though expired) kept re issueing the token ( please note there is no refresh token here to manage it by storing and modifying!!!)

任何提示,即使访问令牌已过期,IDM如何在不引导用户登录屏幕的情况下重新发行令牌? = https://auth0.com/docs/api-auth/tutorials/silent-authentication rel = nofollow noreferrer>静默身份验证。

Any clues how the IDM re issue the token without taking user to login screen, even though the access token is expired??(Silent authentication. ??

推荐答案

实现配置文件服务优先于activeasync

implement profile service overrride 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>();

,同时在配置服务下将身份服务器服务添加到集合中

while adding the identity server service to collection under configure services

 .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都将失效。

I have happened to found a better way i.e. using aspnetuser securitystamp, every time user log-in update the security stamp so that any prior active session/cookies will get invalidated.

_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,当令牌过期时,授权端点将对安全性更改进行验证,如果存在,则将用户重定向到登录名。这样,我们确保只有一个活动会话

i.e. on every login, the security stamp of the user gets updated and pushed to the cookie, when the token expires, the authorize end point will verify on the security change, If there is any then redirects the user to login. This way we are ensuring there will only be one active session

这篇关于身份服务器隐式授予SPA4并发登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 12:49