使用Owin.Security.Providers.LinkedIn.LinkedInAuthenticationProvider时获取Access_Denied响应

时间:2014-08-21 00:58:01

标签: asp.net-mvc oauth asp.net-mvc-5 linkedin

我正在玩Owin.Security.Providers项目以允许我的MVC 5应用程序使用各种社交网络登录。我在LinkedIn中创建了一个应用,并将其范围设置为r_emailaddressr_basicprofile。当我尝试使用LinkedIn accout登录时,我的返回网址上会显示/Login/SigninRedirect?error=access_denied。虽然我设置为CallbackPath网址的/signin-redirect具有codestate属性。在Fiddler中,它看起来像这样:/signin-redirect?code=<code_id>&state=<state_id>。 任何人都有任何想法我可能做错了什么? 这是我的代码:

protected virtual void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        });
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        var linkedInAuthOptions = new LinkedInAuthenticationOptions()
        {
            ClientId = <client_id>,
            ClientSecret = <client_secret>,
            CallbackPath = new PathString("/signin-redirect")
        };
        app.UseLinkedInAuthentication(linkedInAuthOptions);
    }

在我的登录控制器中,我处理登录和重定向类似于VS2013示例:

public class LoginController : Controller
{
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult ExternalLogin(string provider, string returnUrl)
    {
        var redirectUrl = "/Login/SigninRedirect";
        redirectUrl += string.IsNullOrEmpty(returnUrl) ? "" : "?redirectUrl=" + returnUrl;

        return new ChallengeResult(provider, redirectUrl);
    }

    // Redirects from successful social signin to a speccified URL.
    public ActionResult SigninRedirect(string redirectUrl)
    {
        var redirect = string.IsNullOrEmpty(redirectUrl) ? "/" : redirectUrl;

        ExternalLoginInfo loginInfo = AuthenticationManager.GetExternalLoginInfo();
        // loginInfo is null when trying to sign in with LinkedIn
        // works fine for Twitter though
        if (loginInfo != null)
        {
            var authResult = AuthenticationManager.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie).Result;
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

            var claims = authResult.Identity.Claims.ToList();
            claims.Add(new Claim(ClaimTypes.AuthenticationMethod, loginInfo.Login.LoginProvider));

            var claimsIdentity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ExternalCookie);
            AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, claimsIdentity);
        }
        return new RedirectResult(redirect);
    }

    #region Helpers

    private IAuthenticationManager AuthenticationManager
    {
        get
        {
            return HttpContext.GetOwinContext().Authentication;
        }
    }

    private class ChallengeResult : HttpUnauthorizedResult
    {
        private const string XsrfKey = "XsrfId";

        public ChallengeResult(string provider, string redirectUrl, string userId = null)
        {
            LoginProvider = provider;
            RedirectUrl = redirectUrl;
            UserId = userId;
        }

        public string UserId { get; set; }
        public string RedirectUrl { get; set; }
        public string LoginProvider { get; set; }

        public override void ExecuteResult(ControllerContext context)
        {
            var properties = new AuthenticationProperties() {RedirectUri = RedirectUrl};
            if (UserId != null)
            {
                properties.Dictionary[XsrfKey] = UserId;
            }
            context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
        }
    }

    #endregion
}

当我尝试使用Twitter帐户登录时,相同的代码工作正常。

1 个答案:

答案 0 :(得分:1)

发现了这个问题。问题是我为Twitter和LinkedIn提供商注册了相同的CallbackPath/signin-redirect)。像这样:

        var twitterAuthOptions = new TwitterAuthenticationOptions()
        {
            ConsumerKey = <consumerKey>,
            ConsumerSecret = <consumerSecret>,
            CallbackPath = new PathString("/signin-redirect")
        };
        app.UseTwitterAuthentication(twitterAuthOptions);

        var linkedInAuthOptions = new LinkedInAuthenticationOptions()
        {
            ClientId = <clientId>,
            ClientSecret = <clientSecret>,
            CallbackPath = new PathString("/signin-redirect")
        };
        app.UseLinkedInAuthentication(linkedInAuthOptions);

当我设置不同的CallbackPath时,一切都开始正常。