【问题标题】:Proper way to authenticate to Web API from SPA MVC app?从 SPA MVC 应用程序向 Web API 进行身份验证的正确方法?
【发布时间】:2014-09-12 09:46:25
【问题描述】:

所以,我对新的 OWIN 框架的复杂性不是特别强,并且有以下问题:

我有一个 SPA 网络应用程序(最新的 MVC,AngularJs),最新的 OWIN,身份框架已连接到 RavenDB 用户存储(使用 Brock 的提供程序)..

需要:通过 SPA 网站上的用户名/密码或 Twitter/Fb/LiveId 登录用户,并让该操作以安全的方式验证从浏览器发出的未来 Web API 调用。在身份验证期间,我需要向 Web API 传递一些声明,以便它不仅知道用户是谁,还知道他/她的权限。 此外,需要使用 API Keys 将 Web API 作为 API 调用(这部分我想我得到了)。

这样做的正确方法是什么?我还计划在未来也让移动应用程序连接到 Web API。读了很多文章,我的头已经晕了。

问题:我认为使用 cookie 身份验证模式可以为我解决问题。我已经为 Visual Studio 调试模式设置了工作,并认为我很好。但是,当我部署到 Azure 时,我开始从 API 调用中获得 401 Unauthorized。 SPA 网站和 API 都在相同的根域下运行,但在不同的子域下运行。从 Visual Studio 进行本地测试时,我没有使用任何 cookie 域设置。在 Azure 中,我将根域用于 cookie。

这是我的 SPA 的 MVC 应用程序 ConfigAuth:

public void ConfigureAuth(IAppBuilder app)
{
    var decryptor = new SettingsEncryption();

    // 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/Login"),
        LogoutPath = new PathString("/Account/Logout"),
        CookieDomain = CloudConfigurationManager.GetSetting("AuthCookieDomain"),
        CookieSecure = CookieSecureOption.Always,
        //CookiePath = "/",
        CookieHttpOnly = true,
        ExpireTimeSpan = TimeSpan.FromDays(365),
        SlidingExpiration = true,
    });

    // Use a cookie to temporarily store information about a user logging in with a third party login provider
    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

    app.UseMicrosoftAccountAuthentication(
        clientId: decryptor.Decrypt(CloudConfigurationManager.GetSetting("LiveIdOAuthAppId")),
        clientSecret: decryptor.Decrypt(CloudConfigurationManager.GetSetting("LiveIdOAuthSecretKey")));

    app.UseTwitterAuthentication(
       consumerKey: decryptor.Decrypt(CloudConfigurationManager.GetSetting("TwitterOAuthAppId")),
       consumerSecret: decryptor.Decrypt(CloudConfigurationManager.GetSetting("TwitterOAuthSecretKey")));

    app.UseFacebookAuthentication(
       appId: decryptor.Decrypt(CloudConfigurationManager.GetSetting("FacebookOAuthAppId")),
       appSecret: decryptor.Decrypt(CloudConfigurationManager.GetSetting("FacebookOAuthSecretKey")));

    app.UseGoogleAuthentication(
        clientId: decryptor.Decrypt(CloudConfigurationManager.GetSetting("GoogleOAuthAppId")),
        clientSecret: decryptor.Decrypt(CloudConfigurationManager.GetSetting("GoogleOAuthSecretKey")));
}

这是我的 Web API ConfigAuth:

    app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ExternalCookie);

    // Enable the application to use a cookie to store information for the signed in user
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        CookieDomain = CloudConfigurationManager.GetSetting("AuthCookieDomain"),
        CookieSecure = CookieSecureOption.Always,
        //CookiePath = "/",
        CookieHttpOnly = true,
        ExpireTimeSpan = TimeSpan.FromDays(365),
        SlidingExpiration = true,
        Provider = new CookieAuthenticationProvider
        {
            OnApplyRedirect = ApplyRedirect
        },

    });

    //app.UseExternalSignInCookie(DefaultAuthenticationTypes.ApplicationCookie);

    // Uncomment the following lines to enable logging in with third party login providers
    app.UseMicrosoftAccountAuthentication(
        clientId: decryptor.Decrypt(CloudConfigurationManager.GetSetting("LiveIdOAuthAppId")),
        clientSecret: decryptor.Decrypt(CloudConfigurationManager.GetSetting("LiveIdOAuthSecretKey")));

    app.UseTwitterAuthentication(
        consumerKey: decryptor.Decrypt(CloudConfigurationManager.GetSetting("TwitterOAuthAppId")),
        consumerSecret: decryptor.Decrypt(CloudConfigurationManager.GetSetting("TwitterOAuthSecretKey")));

    app.UseFacebookAuthentication(
        appId: decryptor.Decrypt(CloudConfigurationManager.GetSetting("FacebookOAuthAppId")),
        appSecret: decryptor.Decrypt(CloudConfigurationManager.GetSetting("FacebookOAuthSecretKey")));

    app.UseGoogleAuthentication(
        clientId: decryptor.Decrypt(CloudConfigurationManager.GetSetting("GoogleOAuthAppId")),
        clientSecret: decryptor.Decrypt(CloudConfigurationManager.GetSetting("GoogleOAuthSecretKey")));

    var config = GlobalConfiguration.Configuration;
        config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

此外,已在 Web API 上启用了一个全局处理程序来验证每个调用。 (继承自 DelegatingHandler,检查 Headers 是否存在 API Key,否则调用 AssertAuth())

【问题讨论】:

  • 你是否在两个网站都设置了相同的机器密钥?

标签: asp.net-mvc authentication asp.net-web-api owin


【解决方案1】:

好吧,我已经编写了一个教程,涵盖了您想要实现的场景,该教程没有 cookie,并且仅依赖于不记名令牌,这是您构建 SPA 的正确方式,您可以查看该系列的帖子这里http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/

【讨论】:

    猜你喜欢
    • 2017-03-03
    • 1970-01-01
    • 2017-05-06
    • 2016-03-27
    • 2014-04-26
    • 1970-01-01
    • 2017-10-29
    • 2017-06-02
    • 1970-01-01
    相关资源
    最近更新 更多