繁体   English   中英

如何使任何视图知道用户角色(ASP.NET MVC标识)已更改,以强制任何用户在浏览时注销?

[英]How to make any view aware that the User Roles (ASP.NET MVC Identity) have changed in order to force any user to logout while he or she is browsing?

我认为问题标题是不言自明的,也许只是当我说“他或她正在浏览”时的精确度,我是在考虑传播或信号。

我不希望他或她不得不浏览另一个地方只是为了确定Identity SecurityStamp已更改并且已经注销然后可以重定向到主页,我已经这样做了,但是我想知道是否存在框架(我怀疑最有可能是JS),它将使操作更加“实时”。

[编辑]
可能是SignalR的工作,但我还没有尝试过。

我设法通过SignalR获得了可行的解决方案

首先,请注意Startup.Auth.cs SignalR的设置顺序。 如何通过SignalR将消息发送到特定用户(身份ID)? 并且还创建IUserIdProvider的实现,该实现将仅在Cookies和OwinContext之后注册,以使其能够利用身份用户字段(即非null)。

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder appBuilder)
    {
        // Order matters here...
        // Otherwise SignalR won't get Identity User information passed to Id Provider...
        ConfigOwinContext(appBuilder);
        ConfigCookies(appBuilder);
        ConfigSignalR(appBuilder);
    }

    private static void ConfigOwinContext(IAppBuilder appBuilder)
    {
        appBuilder.CreatePerOwinContext(ApplicationDbContext.Create);
        appBuilder.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        appBuilder.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
        appBuilder.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
        appBuilder.CreatePerOwinContext(LdapAdEmailAuthenticator.Create);
    }

    private static void ConfigCookies(IAppBuilder appBuilder)
    {
        appBuilder.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>
                (
                    TimeSpan.FromHours(4),
                    (manager, user) => user.GenerateUserIdentityAsync(manager)
                )
            }
        });
        appBuilder.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
        appBuilder.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
        appBuilder.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
    }

    private static void ConfigSignalR(IAppBuilder appBuilder)
    {
        appBuilder.MapSignalR();
        var idProvider = new HubIdentityUserIdProvider();
        GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => idProvider);
    }
}

public class HubIdentityUserIdProvider : IUserIdProvider
{
    public string GetUserId(IRequest request)
    {
        return request == null
            ? throw new ArgumentNullException(nameof(request))
            : request.User?.Identity?.GetUserId();
    }
}

其次,在服务器端声明一个集线器

public class UserHub : Hub
{
}

第三,在控制器(是否有API)中涉及特定用户注销的更改中,强制注销并更新身份安全标记:

 var userHub = GlobalHost.ConnectionManager.GetHubContext<UserHub>();
 userHub.Clients.User(userId).send("Roles added: " + rolesToAdd.Join() + Environment.NewLine + "Roles removed: " + rolesToRemove.Join());

 return Request.CreateResponse(HttpStatusCode.OK);

第四,使用JS客户端上的集线器,我创建了一个局部视图,该视图仅在当前用户通过身份验证时使用, LoggedOutPartialView.cshtml

@if (Request.IsAuthenticated)
{
    <div class="modal fade" id="loggedOutModal" tabindex="-1" role="dialog" aria-labelledby="loggedOutModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title" id="loggedOutModalLabel">Notification</h4>
                </div>
                <div class="modal-body">
                    <h6 class="align-center">Sorry, but it seems that you just have been logged out!!!</h6>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>

    <script>

        $(function() {
            var userHub = $.connection.userHub;

            console.log(userHub.client);

            userHub.client.logout= function (message) {
                $('#loggedOutModal').modal('show');
            };

            $.connection.hub.start().done(function () {
            });
        });

    </script>
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM