Owin Web 角色不会解密 Owin MVC 应用程序提供的 cookie
Owin web role will not decrypt cookie provided by Owin MVC Application
MVC Web 应用程序
我有一个以前使用 FormsAuthentication 的 MVC 5 网站,此后我已切换到 OWIN 身份验证。使用 OWIN 登录和退出网站工作正常。这是启动配置。
public partial class Startup
{
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/LogOn")
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}
它在登录时有一些基本的声明设置...
public void SignIn(string username, bool remember, string userData)
{
var claims = new List<Claim>();
var user = JsonConvert.DeserializeObject<VastIdentity>(userData);
// create *required* claims
claims.Add(new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()));
claims.Add(new Claim(ClaimTypes.Name, username));
// custom – serialised user state
claims.Add(new Claim("userState", userData));
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties()
{
AllowRefresh = true,
IsPersistent = remember,
ExpiresUtc = DateTime.UtcNow.AddDays(7)
}, identity);
}
一切正常,用户可以使用适当的 cookie 登录和退出 MVC 应用程序。
SignalR Web 角色
我有一个单独的 Azure Web 角色来托管信号器。它具有以下启动...
public class Startup
{
public void Configuration(IAppBuilder app)
{
//GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new CustomUserIdProvider());
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
AuthenticationMode = AuthenticationMode.Active,
CookieName = ".AspNet.ApplicationCookie",
Provider = new CustomAuthProvider()
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
// EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
}
}
问题 1: 当连接到 SignalR 集线器并调用 OnConnected 时,Context.User.Identity 是一个空的 GenericPrincipal,不包含来自网站的声明曲奇饼。这就是我要实施自定义身份验证提供程序并自己设置身份的原因。不过好像没用
public class NotificationHub : Hub
{
// snip
public override Task OnConnected()
{
string name = Context.User.Identity.Name;
_Connections.Add(name, Context.ConnectionId);
return base.OnConnected();
}
}
当我检查上下文中的 cookie 时,我可以看到加密的 .AspNet.ApplicationCookie 随请求一起传递。但是我不知道如何让 OWIN 解密它并使用可用的声明。
问题 2: 自定义身份验证提供程序永远不会 运行。当我在其中设置断点时,它永远不会进入任何一种方法。
public class CustomAuthProvider : CookieAuthenticationProvider
{
public override void ResponseSignIn(CookieResponseSignInContext context)
{
// do some custom stuff here
base.ResponseSignIn(context);
}
public override Task ValidateIdentity(CookieValidateIdentityContext context)
{
// do some custom stuff here
return base.ValidateIdentity(context);
}
}
我对 OWIN 身份验证没有太多经验。任何人都可以看到信号器网络角色 cookie 身份验证可能出了什么问题吗?
拔掉头发后,我重新检查了 owin nugget 包的版本,发现 Web 应用程序使用的是 3.0.1,而 SignalR Web 角色使用的是 2.x。
解决方案是确保 owin 库在应用程序之间的版本相同。 owin 似乎无法解密从不同版本生成的 cookie。
编辑:由于解密 cookie 的问题与版本不匹配有关,因此不需要自定义身份验证提供程序和 cookie 名称。
这导致以下简单的 owin 在 web 角色中初始化...
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
AuthenticationMode = AuthenticationMode.Active,
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
// EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
}
}
MVC Web 应用程序
我有一个以前使用 FormsAuthentication 的 MVC 5 网站,此后我已切换到 OWIN 身份验证。使用 OWIN 登录和退出网站工作正常。这是启动配置。
public partial class Startup
{
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/LogOn")
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}
它在登录时有一些基本的声明设置...
public void SignIn(string username, bool remember, string userData)
{
var claims = new List<Claim>();
var user = JsonConvert.DeserializeObject<VastIdentity>(userData);
// create *required* claims
claims.Add(new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()));
claims.Add(new Claim(ClaimTypes.Name, username));
// custom – serialised user state
claims.Add(new Claim("userState", userData));
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties()
{
AllowRefresh = true,
IsPersistent = remember,
ExpiresUtc = DateTime.UtcNow.AddDays(7)
}, identity);
}
一切正常,用户可以使用适当的 cookie 登录和退出 MVC 应用程序。
SignalR Web 角色
我有一个单独的 Azure Web 角色来托管信号器。它具有以下启动...
public class Startup
{
public void Configuration(IAppBuilder app)
{
//GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new CustomUserIdProvider());
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
AuthenticationMode = AuthenticationMode.Active,
CookieName = ".AspNet.ApplicationCookie",
Provider = new CustomAuthProvider()
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
// EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
}
}
问题 1: 当连接到 SignalR 集线器并调用 OnConnected 时,Context.User.Identity 是一个空的 GenericPrincipal,不包含来自网站的声明曲奇饼。这就是我要实施自定义身份验证提供程序并自己设置身份的原因。不过好像没用
public class NotificationHub : Hub
{
// snip
public override Task OnConnected()
{
string name = Context.User.Identity.Name;
_Connections.Add(name, Context.ConnectionId);
return base.OnConnected();
}
}
当我检查上下文中的 cookie 时,我可以看到加密的 .AspNet.ApplicationCookie 随请求一起传递。但是我不知道如何让 OWIN 解密它并使用可用的声明。
问题 2: 自定义身份验证提供程序永远不会 运行。当我在其中设置断点时,它永远不会进入任何一种方法。
public class CustomAuthProvider : CookieAuthenticationProvider
{
public override void ResponseSignIn(CookieResponseSignInContext context)
{
// do some custom stuff here
base.ResponseSignIn(context);
}
public override Task ValidateIdentity(CookieValidateIdentityContext context)
{
// do some custom stuff here
return base.ValidateIdentity(context);
}
}
我对 OWIN 身份验证没有太多经验。任何人都可以看到信号器网络角色 cookie 身份验证可能出了什么问题吗?
拔掉头发后,我重新检查了 owin nugget 包的版本,发现 Web 应用程序使用的是 3.0.1,而 SignalR Web 角色使用的是 2.x。
解决方案是确保 owin 库在应用程序之间的版本相同。 owin 似乎无法解密从不同版本生成的 cookie。
编辑:由于解密 cookie 的问题与版本不匹配有关,因此不需要自定义身份验证提供程序和 cookie 名称。
这导致以下简单的 owin 在 web 角色中初始化...
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
AuthenticationMode = AuthenticationMode.Active,
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
// EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
}
}