当我尝试访问我的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);
}
}
}
答案 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();
});
}