【问题标题】:Null Context.User空上下文用户
【发布时间】:2017-02-18 19:21:17
【问题描述】:

当我尝试访问集线器中的 Context.User 时,我不断收到 Context.User is null 错误。我尝试在 ConfigureAuth() 下移动 app.MapSignalR() 但这会导致 SignalR 根本不映射。我不确定我需要在哪里将我的 cookie 传递给 SignalR。

SignalR 在我的应用程序中工作,用于向所有用户发送消息我只是无法让 OnConnect 覆盖在没有 Context.User 的情况下工作

启动.CS

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR();
        ConfigureAuth(app);

    }
}

Startup.Auth.cs

public partial class Startup
{
    private static string clientId =       ConfigurationManager.AppSettings["ida:ClientId"];
    private static string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
    private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
    private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
    private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
    private static string authority = aadInstance + tenantId;

    public void ConfigureAuth(IAppBuilder app)
    {

        app.MapWhen(context => !IsDataPath(context.Request), appBuilder =>
        {
            appBuilder.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            appBuilder.UseCookieAuthentication(new CookieAuthenticationOptions());

            appBuilder.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    //AuthenticationMode = AuthenticationMode.Passive,
                    ClientId = clientId,
                    Authority = authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,

                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        SecurityTokenValidated = (context) =>
                        {
                            var claimsIdentity = context.AuthenticationTicket.Identity;
                            CleanupClaims(claimsIdentity);
                            AddHboClaims(claimsIdentity);
                            context.AuthenticationTicket.Properties.ExpiresUtc = DateTime.Now.AddDays(1).ToUniversalTime();
                            return Task.CompletedTask;
                        },
                        AuthenticationFailed = (context) =>
                        {
                            if (context.Exception.Message.StartsWith("OICE_20004") || context.Exception.Message.Contains("IDX10311"))
                            {
                                context.SkipToNextMiddleware();
                                return Task.FromResult(0);
                            }
                            return Task.FromResult(0);
                        },
                    }
                });
        });
    }

    private bool IsDataPath(Microsoft.Owin.IOwinRequest request)
    {
        return request.Path.Value.StartsWith("/data");
    }

    private void CleanupClaims(ClaimsIdentity claimsIdentity)
    {
        //Remove long unecessary claim types to make the cookie smaller
        claimsIdentity.RemoveClaim(ClaimTypes.Surname);
        claimsIdentity.RemoveClaim(ClaimTypes.GivenName);
        claimsIdentity.RemoveClaim("onprem_sid");
        claimsIdentity.RemoveClaim("http://schemas.microsoft.com/identity/claims/tenantid");
        claimsIdentity.RemoveClaim("http://schemas.microsoft.com/claims/authnmethodsreferences");
        claimsIdentity.RemoveClaim("ipaddr");
    }

    private void AddHboClaims(ClaimsIdentity claimsIdentity)
    {
        var depResolver = AutofacDependencyResolver.Current;
        var permissionRespository = (IUserPermissionsRepository)depResolver.GetService(typeof(IUserPermissionsRepository));
        var emailClaim = claimsIdentity.FindFirst(ClaimTypes.Upn);
        var userPermissions = permissionRespository.GetPermissionForUser(emailClaim.Value);
        foreach (var permission in userPermissions)
        {
            claimsIdentity.AddClaim(HboClaimsNames.Permission, ((int)permission).ToString());
        }

        var db = (Database.HboDbContext)depResolver.GetService(typeof(Database.HboDbContext));
        var resource = db.Resources.SingleOrDefault(r => r.HmbEmail == emailClaim.Value);
        if (resource != null)
        {
            //if (resource.IsActive)
            //{
                claimsIdentity.AddClaim(HboClaimsNames.ResourceId, resource.Id.ToString());
            //}
            //else
            //{
            //    var ex = new Exception("Inactive user attempting to log into HBO: " + emailClaim.Value);
            //    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
            //    
            //}
        }
        else
        {
            var ex = new Exception("User attempting to log into HBO that is not in Db: " + emailClaim.Value);
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
        }
    }
}

【问题讨论】:

    标签: c# .net signalr


    【解决方案1】:

    你需要改变这个:

    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR();        
        ConfigureAuth(app);
    }
    

    到这里:

    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }
    

    然后在您的ConfigureAuth() 中调用MapSignalR()

    ConfigureAuth() 之后不能只调用MapSignalR() 的原因是因为这行:

    app.MapWhen(context => !IsDataPath(context.Request), appBuilder =>
    

    问题的根源在于MapWhen() 方法分支了请求管道,如果您只是在 Owin Startup 中调用 app.MapSignalR(),您将在错误的请求管道中初始化 SignalR。

    所以您的 ConfigureAuth() 方法应该类似于:

    public void ConfigureAuth(IAppBuilder app)
    {
        app.MapWhen(context => !IsDataPath(context.Request), appBuilder =>
        {
            appBuilder.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
            appBuilder.UseCookieAuthentication(new CookieAuthenticationOptions());
    
            appBuilder.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = clientId,
                    Authority = authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,
    
                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        SecurityTokenValidated = (context) =>
                        {
                            ...
                        },
                        AuthenticationFailed = (context) =>
                        {
                            ...
                        },
                    }
                });
    
            appBuilder.MapSignalR();
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-30
      • 2018-12-31
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-13
      相关资源
      最近更新 更多