背景
我们的 Web 应用程序使用外部 身份验证,从某种意义上说,用户的用户名/密码未在本地验证,而是在 Web 应用程序“外部”以中央、单点登录的方式进行验证在类型网站上。身份验证证明(和用户身份)可通过本地服务器变量(HTTP_EMPLOYEEID
等)获得。但是,它并不像针对 Google、Facebook 或其他基于 OAuth 的设置进行身份验证那样外部。所以我只是想做出这种区分,这样它就不会与 ASP.NET Identity/Owin 中的术语“外部登录”发生冲突。
问题
我正在尝试找出一种干净的方法来利用经过身份验证的用户数据(来自服务器变量)并将其传递给 ASP.NET 身份验证。但是,在用户登录到应用程序之前,必须针对 Web 服务查找用户配置文件和角色数据。
我想使用 Owin 和基于声明的身份,但我不确定我是否也应该使用 ASP.NET Identity,或者只是做一个更“纯粹”的声明实现.我喜欢不重新发明轮子的想法,但我也不想将方钉强行插入圆孔(俗话说),如果用户识别方式和从网络服务中查找的方式不适合典型的 ASP.NET Identity 用法。
例如,如果我采用更纯粹的方法,我可以这样做:
// 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 Identity(只是没有 Entity Framework 的东西),并且只实现 IUser、IUserStore、IRoleStore(以及任何其他最低要求),并使用 Microsoft 现有的、已建立的框架处理这个。争论点是这更符合当前标准,并且可能更容易扩展到其他类型的身份验证(如果本地用户名/密码或 Google/Facebook 最终成为其他允许的身份验证选项,除了当前基于 ServerVariables 的设置)。
以前走这条路的人有什么建议吗?我是否应该将服务器变量注入(inject)数据视为自定义中间件并通过 ASP.NET Identity 加以利用,或者只是不担心在那个世界中适合它的位置,而更像是一个“纯粹主义者”方法如上所述?
附注我使用的是 ASP.NET 4.6.1,而不是新的 ASP.NET Core。
最佳答案
我有类似的饱和度。我不想使用整个 ASP.Net Identity,因为我需要通过外部身份验证再次对用户进行身份验证。
所以我只使用 OWIN Claim Authentication,它基本上使用 Claims 创建身份验证 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);
}
}
启动.cs
注意:我有同时使用 MVC 和 Web API 的 Angular,所以我为 REST 返回 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);
}
}
关于c# - 具有 "external"身份验证的 ASP.NET MVC 基于声明的用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38489384/