我们的网络应用程序使用外部身份验证,从某种意义上说,用户的用户名/密码未在本地验证,但正在Web应用程序“外部”进行验证,并在中央单点登录在类型网站上。验证证明(和用户的标识)可通过本地服务器变量(HTTP_EMPLOYEEID
等)获得。但是,它不像外部那样对Google,Facebook或其他基于OAuth的设置进行身份验证。所以我只想做出这种区分,因此它不会与ASP.NET Identity / Owin中的“外部登录”术语发生冲突。
我正在尝试找出一种 clean 方式来利用经过身份验证的用户数据(来自服务器变量)并将其传递给ASP.NET身份验证。但是,在用户登录应用程序之前,必须在Web服务中查找用户配置文件和角色数据。
我想使用Owin和基于声明的身份,但我不确定是否也应该使用 ASP.NET身份,或者只是使用声明进行更“纯粹”的实现。我喜欢不重新发明轮子的想法,但是我也不想强迫方形钉进入圆孔(如上所述),如果用户被识别并从Web服务中查找的方式不适合典型的 ASP.NET标识用法。
例如,如果我采取更纯粹的方法,我可以做类似的事情:
// Get the current user's id
var userId = HttpContext.Current.Request.ServerVariables["HTTP_EMPLOYEEID"];
// Get profile and role data from a web service
MyUser user = MyUserService.GetUserById(userId);
// Create claims
var claims = new Claim[]
{
new Claim(ClaimTypes.Name, user.Id),
new Claim(ClaimTypes.Email, user.Email),
new Claim(ClaimTypes.Role, user.Role), // there can be more roles, but you get the idea
// etc.
};
// Establish identity and login
var identity = new ClaimsIdentity(claims, "CookieAuthentication");
HttpContext.Current.GetOwinContext().Authentication.SignIn(identity);
但我也知道我可以使用ASP.NET身份(只是没有实体框架的东西),只需实现IUser,IUserStore,IRoleStore(以及其他任何最低要求),并使用Microsoft现有的已建立框架处理这个。其论点是,这更符合当前标准,并且可能更容易扩展到其他类型的身份验证(例如,如果是本地用户名/密码,或Google / Facebook最终成为其他允许的身份验证选项,除了当前的基于ServerVariables的设置。)
之前曾经走过这条路的人的建议是什么?我应该将服务器变量注入的数据视为自定义中间件并通过ASP.NET身份来利用它,或者只是不担心在那个世界中适合它的地方,并进入更多的“纯粹主义者”如上所述的方法?
P.S。我使用的是ASP.NET 4.6.1,而不是新的ASP.NET Core。
答案 0 :(得分:2)
我有类似的饱和度。我不想使用整个ASP.Net Identity,因为我需要再次验证用户的外部身份验证。
所以我只使用OWIN声明身份验证,它基本上创建了声明的身份验证cookie; 与我们过去使用的表单身份验证类似。
public class OwinAuthenticationService
{
private readonly HttpContextBase _context;
private const string AuthenticationType = "ApplicationCookie";
public OwinAuthenticationService(HttpContextBase context)
{
_context = context;
}
public void SignIn(User user)
{
IList<Claim> claims = new List<Claim>
{
new Claim(ClaimTypes.Sid, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.GivenName, user.FirstName),
new Claim(ClaimTypes.Surname, user.LastName),
};
foreach (Role role in user.Roles)
{
claims.Add(new Claim(ClaimTypes.Role, role.Name));
}
ClaimsIdentity identity = new ClaimsIdentity(claims, AuthenticationType);
IOwinContext context = _context.Request.GetOwinContext();
IAuthenticationManager authenticationManager = context.Authentication;
authenticationManager.SignIn(identity);
}
public void SignOut()
{
IOwinContext context = _context.Request.GetOwinContext();
IAuthenticationManager authenticationManager = context.Authentication;
authenticationManager.SignOut(AuthenticationType);
}
}
注意:我使用MVC和Web API都有Angular,所以我返回404消息而不是404页面。
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "ApplicationCookie",
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnApplyRedirect = ctx =>
{
if (!IsApiRequest(ctx.Request))
{
ctx.Response.Redirect(ctx.RedirectUri);
}
}
}
});
}
private static bool IsApiRequest(IOwinRequest request)
{
string apiPath = VirtualPathUtility.ToAbsolute("~/api/");
return request.Uri.LocalPath.ToLower().StartsWith(apiPath);
}
}