空的Context.User

时间:2017-02-18 19:21:17

标签: c# .net signalr

当我尝试访问我的Hub中的Context.User时,我一直得到Context.User是空错误。我尝试在ConfigureAuth()下移动app.MapSignalR(),但这会导致SignalR根本不映射。我不确定我需要将cookie传递给SignalR。

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

Startup.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);
        }
    }
}

1 个答案:

答案 0 :(得分:2)

你需要改变这个:

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

对此:

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

MapSignalR()

中拨打ConfigureAuth()

MapSignalR()之后只能致电ConfigureAuth()的原因是:

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();
    });
}