Web API不接受外部身份提供程序令牌

时间:2017-04-14 15:43:32

标签: authentication asp.net-web-api oauth owin access-token

现在已经挣扎了几个星期,最后决定是时候寻求帮助了。

我有一个MVC网站,以及带有Web Api后端的Xamarin.Forms应用程序,都需要身份验证。 MVC项目很容易实现,因为项目模板完成了大部分工作。现在让webApi实现相同的提供程序并不像我希望的那么容易。

我已经在Xamarin.forms项目中实现了Xamarin.Auth,以至于我为每个提供UI的身份提供者提供了一个按钮,并且在有效身份验证中为我提供了一个访问令牌。下一步是将此外部令牌交换为由我的web api(本地机构)生成的令牌。当我在http标头中包含外部令牌时,标头格式为" Authorization Bearer access_token"我期望web api验证令牌并填写User.Identity以及声明。

这是我的Startup.Auth.cs

        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(IdentityEntities.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // Configure the application for OAuth based flow
        PublicClientId = "self";
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            // In production mode set AllowInsecureHttp = false
            AllowInsecureHttp = true
        };

        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(OAuthOptions);


        //var issuer = "http://localhost:59822";
        var issuer = "https://brenockideapipelinewebapiauth.azurewebsites.net";
        string audienceId = ConfigurationManager.AppSettings["as:AudienceId"];
        byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["as:AudienceSecret"]);

        app.UseJwtBearerAuthentication(
            new JwtBearerAuthenticationOptions
            {
                AuthenticationMode = AuthenticationMode.Active,
                AllowedAudiences = new[] { audienceId },
                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                {
                    new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
                }
            });

        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
                },
            });

        var fbauth = new FacebookAuthenticationOptions() { AppId = "appid", AppSecret = "secret" };
        fbauth.Scope.Add("email");
        fbauth.UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name";
        app.UseFacebookAuthentication(fbauth);

        app.UseTwitterAuthentication(new Microsoft.Owin.Security.Twitter.TwitterAuthenticationOptions()
        {
            ConsumerKey = ConfigurationManager.AppSettings["TwitterConsumerKey"].ToString(),
            ConsumerSecret = ConfigurationManager.AppSettings["TwitterConsumerSecret"].ToString(),twitter"),
            //certificate errors without this
            BackchannelCertificateValidator = new CertificateSubjectKeyIdentifierValidator(new[]
            {
                "A5EF0B11CEC04103A34A659048B21CE0572D7D47", // VeriSign Class 3 Secure Server CA - G2
                "0D445C165344C1827E1D20AB25F40163D8BE79A5", // VeriSign Class 3 Secure Server CA - G3
                "7FD365A7C2DDECBBF03009F34339FA02AF333133", // VeriSign Class 3 Public Primary Certification Authority - G5
                "39A55D933676616E73A761DFA16A7E59CDE66FAD", // Symantec Class 3 Secure Server CA - G4
                "5168FF90AF0207753CCCD9656462A212B859723B", //DigiCert SHA2 High Assurance Server C‎A 
                "B13EC36903F8BF4701D498261A0802EF63642BC3",  //DigiCert High Assurance EV Root CA
                "‎add53f6680fe66e383cbac3e60922e3b4c412bed", // Symantec Class 3 EV SSL CA - G3
                "4eb6d578499b1ccf5f581ead56be3d9b6744a5e5", // VeriSign Class 3 Primary CA - G5
            })
        });

        app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
        {
            ClientId = ConfigurationManager.AppSettings["GoogleClientId"].ToString(),
            ClientSecret = ConfigurationManager.AppSettings["GoogleClientSecret"].ToString()
        });

        app.UseLinkedInAuthentication
        (
            new LinkedInAuthenticationOptions()
            {
                ClientId = ConfigurationManager.AppSettings["LinkedInAPIKey"].ToString(),
                ClientSecret = ConfigurationManager.AppSettings["LinkedInAPISecret"].ToString()
            }
        );
    }

这是我认为我需要用来为本地令牌交换外部令牌的控制器操作。

// GET api/Account/ExternalLogin
    [OverrideAuthentication]
    [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
    [AllowAnonymous]
    [Route("ExternalLogin", Name = "ExternalLogin")]
    public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
    {
        if (error != null)
        {
            return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
        }

        if (!User.Identity.IsAuthenticated)
        {
            return new ChallengeResult(provider, this);
        }

        ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);

        if (externalLogin == null)
        {
            return InternalServerError();
        }

        if (externalLogin.LoginProvider != provider)
        {
            Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            return new ChallengeResult(provider, this);
        }

        ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
            externalLogin.ProviderKey));

        bool hasRegistered = user != null;

        if (hasRegistered)
        {
            Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);

            ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
               OAuthDefaults.AuthenticationType);
            ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
                CookieAuthenticationDefaults.AuthenticationType);

            AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
            Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
        }
        else
        {
            IEnumerable<Claim> claims = externalLogin.GetClaims();
            ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
            Authentication.SignIn(identity);
        }

        return Ok();
    }

为什么我的WEB API不接受外部令牌?

0 个答案:

没有答案