使用UseCookieAuthentication和现有Web API OAuth应用程序验证MVC应用程序

时间:2014-12-08 17:53:06

标签: asp.net-mvc asp.net-mvc-4 authentication oauth

我使用自定义的 Microsoft.Owin 实现创建了自己的web api OAuth身份验证服务器:

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        PublicClientId = "self";
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId),
            AuthorizeEndpointPath = new PathString("/Auth/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };

        app.UseOAuthBearerTokens(OAuthOptions);

现在我想在外部mvc应用程序中使用该OAuth身份验证,但我真的很困惑。 实际上,我主要关心的是根据我现有的OAuth服务器授权控制器和操作。

经过2天的研究,我最终根据自定义 OAuthBearerAuthenticationProvider 实施了该功能,该功能基于登录过程中创建的Cookie工作。功能正常但我认为(实际上我知道)有些不对劲。 这是我的自定义 OAuthBearerAuthenticationProvider

public class ApplicationOAuthBearerAuthenticationProvider : OAuthBearerAuthenticationProvider
{
    public override Task RequestToken(OAuthRequestTokenContext context)
    {
        if (context == null) 
            throw new ArgumentNullException("context");

        var tokenCookie = context.OwinContext.Request.Cookies["BearerToken"];

        if (!string.IsNullOrEmpty(tokenCookie))
        {
            context.Token = tokenCookie;
        }

        return Task.FromResult<object>(null);
    }
}

这是我的MVC auth启动配置方法:

public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Auth/SignIn")
        });

        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
        {
            Provider = new ApplicationOAuthBearerAuthenticationProvider(),
        });
    }

如果有人有相关经验,请告诉我。


更新:我认为我最终找到了解决方案。

在登录过程中的解决方案中,我创建了一张故障单,并在 OAupBearerOptions 内保护,该内容在 Startup.Auth 类中定义。

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SignIn(LoginPageModel pageModel, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return RedirectToAction("SignIn", new { returnUrl = returnUrl });
    }

    try
    {
        var result = await AuthService.Instance.AuthenticateAsync(pageModel.LoginModel);

        CreateIdentity(result);

        return RedirectToLocal(returnUrl);
    }
    catch (Exception ex)
    {
        return RedirectToAction("SignIn", new { returnUrl = returnUrl });
    }
}

private void CreateIdentity(TokenResponseModel result)
{
    IDictionary< String, String> data = new Dictionary< String, String>
    {
        { "userName", result.Username }
    };

    var claims = new List<Claim>();
    claims.Add(new Claim(ClaimTypes.Name, result.Username));
    claims.Add(new Claim(ClaimTypes.Email, result.Username));

    if (!String.IsNullOrEmpty(result.ExternalIdentity))
    {
        claims.Add(new Claim(CustomClaimTypes.ExternalIdentity, result.ExternalIdentity));
    }

    if (result.Roles != null && result.Roles.Length != 0)
    {
        foreach (var role in result.Roles)
        {
            claims.Add(new Claim(ClaimTypes.Role, role));
        }
    }

    ClaimsIdentity oAuthIdentity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
    ClaimsIdentity cookiesIdentity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);

    AuthenticationProperties properties = new AuthenticationProperties(data);
    AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);

    Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
    AuthenticationManager.SignIn(cookiesIdentity);
}

验证配置更改为:

public void ConfigureAuth(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Auth/SignIn"),
    });

    OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
    app.UseOAuthBearerAuthentication(OAuthBearerOptions);
}

0 个答案:

没有答案