5

我正在设置我的第一个 MVC Web 应用程序。我知道我需要提供基于表单的身份验证模型,并且我知道我还将为多个其他内部 Web 应用程序重用它。

MVC 5 身份验证的所有文档(我相信它们都是基于 OWIN 的东西)使用 EF Code First 将其“烘焙”到单个 Web 应用程序中。

我正在尝试的是拥有另一个 Web 应用程序,我将除帐户内容之外的所有内容都剥离出来,然后尝试“指向”我的 Web 应用程序身份验证,并让它返回一个“令牌”,我猜是我的认证用户和他/她的“角色”。

我在正确的轨道上吗?我是不是让这件事复杂化了?我是 Web 开发的新手,但这似乎是一个相当合理和直接的请求。傻眼了,到处都找不到。

4

4 回答 4

13

详细说明 我正在寻找一种使用 OWIN 而不是 FormsAuthentication 的方法,但没有所有用户管理器、用户存储的东西。我想你也想要同样的。

在您的登录操作中,使用您自己的代码检查数据库中的用户凭据,如果用户正确,则使用所需信息创建声明并使用这些声明调用 AuthenticationManager.SignIn:

var claims = new List<Claim>
{
    new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())
    ,new Claim(ClaimTypes.Name, user.UserName)
    ,new Claim(ClaimTypes.Email, user.Email)
};
var identity = new ClaimsIdentity(claims,
                            DefaultAuthenticationTypes.ApplicationCookie);

HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);

现在您就像 FormsAuthentication.SetAuthCookie 方法一样登录。

现在您可以通过声明获取用户信息:

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    if (filterContext.HttpContext.User.Identity.IsAuthenticated)
    {
        var ctx = filterContext.HttpContext.Request.GetOwinContext();
        var identity = (ClaimsPrincipal)filterContext.HttpContext.User;
        var enumerable = identity.Claims as IList<Claim> ?? identity.Claims.ToList();
        var username = enumerable.Where(x => x.Type == ClaimTypes.Name).Select(x => x.Value).FirstOrDefault();
        var userId = enumerable.Where(x => x.Type == ClaimTypes.NameIdentifier).Select(x => x.Value).FirstOrDefault();

    }
    base.OnActionExecuting(filterContext);
}

您可以控制它,而不是 MVC 模板附带的所有 EF 代码拳头东西

于 2013-11-07T20:22:14.727 回答
5

使用新的OWIN 身份 API,该 API 包含使用应用程序和外部登录cookie 所需的所有内容,如下所示:

public class IdentityAuthenticationManager
{
    public IdentityAuthenticationManager();
    public IdentityAuthenticationManager(IdentityStoreManager storeManager);

    public string ClaimsIssuer { get; set; }
    public string RoleClaimType { get; set; }
    public IdentityStoreManager StoreManager { get; set; }
    public string UserIdClaimType { get; set; }
    public string UserNameClaimType { get; set; }

    public virtual void Challenge(HttpContextBase context, string authenticationType, string redirectUrl);
    public virtual Task<bool> CheckPasswordAndSignIn(HttpContextBase context, string userName, string password, bool isPersistent);
    public virtual Task<bool> CreateAndSignInExternalUser(HttpContextBase context, string loginProvider, IUser user);
    public virtual IEnumerable<Microsoft.Owin.Security.AuthenticationDescription> GetExternalAuthenticationTypes(HttpContextBase context);
    public virtual Task<ClaimsIdentity> GetExternalIdentity(HttpContextBase context);
    public virtual Task<IList<Claim>> GetUserIdentityClaims(string userId, IEnumerable<Claim> claims);
    public virtual Task<bool> LinkExternalIdentity(ClaimsIdentity id, string userId, string loginProvider);
    public virtual Task SignIn(HttpContextBase context, string userId, bool isPersistent);
    public virtual Task SignIn(HttpContextBase context, string userId, IEnumerable<Claim> claims, bool isPersistent);
    public virtual Task<bool> SignInExternalIdentity(HttpContextBase context, ClaimsIdentity id, string loginProvider);
    public virtual void SignOut(HttpContextBase context);
    public virtual bool VerifyExternalIdentity(ClaimsIdentity id, string loginProvider);
}

下面显示了ASP.NET MVC 模板的登录代码:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        // Validate the user password
        if (await AuthenticationManager.CheckPasswordAndSignIn(HttpContext, model.UserName, model.Password, model.RememberMe))
        {
            return RedirectToLocal(returnUrl);
        }
    }

    // If we got this far, something failed, redisplay form
    ModelState.AddModelError("", "The user name or password provided is incorrect.");
    return View(model);
}

欲了解更多信息,请访问

于 2013-11-07T18:55:37.787 回答
3

多个 web 应用程序的单一身份验证位置,可以使用许多不同的方法添加。首先,这里有两个。

  1. 使用 OWIN 框架OAuthAuthorizationServerProvider:创建一个应用程序作为 oAuth 服务器。设置其他人重定向到您的 oAuth 服务器进行身份验证。
  2. 使用身份联合方法:查看 Windows 身份联合。(Thinktecture IdentityServer V2 是一个易于实现的安全令牌服务。IdentityServerV2 除了 STS 之外还有很多功能。)
于 2013-11-06T15:59:06.620 回答
1

如果您正在寻找的只是一个通用的身份验证方案,例如,用户通过一个通用数据库进行身份验证,请实现一个 asp.net MVC Web 服务。这样,每个网站都可以使用您的身份验证服务,并由 IIS 托管和管理。有关 Web API 的信息可以在这里找到http://www.asp.net/web-api/overview。使用 Visual Studio 中的标准深度发布模型将服务部署到 Web 服务器。

于 2013-11-07T06:20:37.883 回答