2015-05-26 22 views
8

Web API 2 Kimlik özelliğini kullanmakta bazı sorunum var. Projede.Web API 2 kimliği./Token Her zaman geri dön 404 hatası

namespace MyNamespace 
{ 
    public partial class Startup 
    { 
     public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; } 
     public static string PublicClientId { get; private set; } 
     public void ConfigureAuth(IAppBuilder app) 
     { 
      app.UseCookieAuthentication(new CookieAuthenticationOptions()); 
      app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 

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

      app.UseOAuthBearerTokens(OAuthOptions); 
     } 
    } 
} 

Aynı şekilde ben fonksiyonel Kullanıcı uygulamak: Token yetkilendirmeyi etkinleştirmek için Bundan sonra

using Microsoft.Owin; 
using Owin; 

[assembly: OwinStartup(typeof(MyNamespace.Startup))] 
namespace MyNamespace 
{ 
    public partial class Startup 
     { 
      public void Configuration(IAppBuilder app) 
      { 
       ConfigureAuth(app); 
      } 
     } 
} 

Ben kısmi sınıfını ekleyin:

Ben StartUp.cs Bunun gibi

eklemek (UserStore, UserManager gibi).

Örnek olarak "ExternalLogin" yöntemini alıyorum ve değiştirin. Bundan sonra

// GET api/Account/ExternalLogin 
    [OverrideAuthentication] 
    [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)] 
    [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); 
     } 

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

     bool hasRegistered = user != null; 

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



      ClaimsIdentity oAuthIdentity = await UserManager.CreateIdentityAsync(user, 
           OAuthDefaults.AuthenticationType); 

      ClaimsIdentity cookieIdentity = await UserManager.CreateIdentityAsync(user, 
           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(); 
    } 

böyle bir uygulamanın başvurumu ve denenmiş giriş çalıştırın:

var loginData = { 
      grant_type: 'password', 
      username: "test", 
      password: "test" 
     }; 

$.ajax({ 
     type: 'POST', 
     url: '/Token', 
     data: loginData 
     }).done(function (data) { 
      alert(data.username); 
      sessionStorage.setItem(tokenKey, data.access_token); 
     }).fail(function (data) { 
      alert(data); 
     }); 

Ben 404 hata var. Fiddler aracılığıyla/Token'e özel istek göndermeyi denedim ve bu da aynı sonucu verdi. Sonra api/Account/ExternalLogin eylemimin mevcut olduğunu kontrol ediyorum, bu yanıt 401 durum kodu. Referansları incelerim Owin, Microsoft.Owin hepsi doğru. Sorun ne? Nerede problemim var?

UPD:

public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider 
{ 
    private readonly string _publicClientId; 

    [Dependency] 
    public ICustomUserManager UserManager 
    { 
     get;set; 
    } 

    public ApplicationOAuthProvider(string publicClientId) 
    { 
     if (publicClientId == null) 
     { 
      throw new ArgumentNullException("publicClientId"); 
     } 

     _publicClientId = publicClientId; 
    } 

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
    { 
     var userManager = context.OwinContext.GetUserManager<ICustomUserManager>(); 

     User user = await userManager.FindAsync(context.UserName, context.Password); 

     if (user == null) 
     { 
      context.SetError("invalid_grant", "The user name or password is incorrect."); 
      return; 
     } 

     ClaimsIdentity oAuthIdentity = await UserManager.CreateIdentityAsync(user, 
           OAuthDefaults.AuthenticationType); 

     ClaimsIdentity cookieIdentity = await UserManager.CreateIdentityAsync(user, 
           CookieAuthenticationDefaults.AuthenticationType); 

     AuthenticationProperties properties = CreateProperties(user.UserName); 
     AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); 

     var val = context.Validated(ticket); 
     context.Request.Context.Authentication.SignIn(cookieIdentity); 
    } 

    public override Task TokenEndpoint(OAuthTokenEndpointContext context) 
    { 
     foreach (KeyValuePair<string, string> property in context.Properties.Dictionary) 
     { 
      context.AdditionalResponseParameters.Add(property.Key, property.Value); 
     } 

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

    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
    { 
     // Resource owner password credentials does not provide a client ID. 
     if (context.ClientId == null) 
     { 
      context.Validated(); 
     } 

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

    public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) 
    { 
     if (context.ClientId == _publicClientId) 
     { 
      Uri expectedRootUri = new Uri(context.Request.Uri, "/"); 

      if (expectedRootUri.AbsoluteUri == context.RedirectUri) 
      { 
       context.Validated(); 
      } 
     } 

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

    public static AuthenticationProperties CreateProperties(string userName) 
    { 
     IDictionary<string, string> data = new Dictionary<string, string> 
     { 
      { "userName", userName } 
     }; 
     return new AuthenticationProperties(data); 
    } 
} 
+0

"ApplicationOAuthProvider" yönteminizin kodunu ekleyebilir misiniz? –

+0

IoC için birliği kullanıyorum. Ve UserManager parçasını yeniden yazınız – CMaker

cevap

25

Bu problemde anlamaya. OAuthAuthorizationServerOptions, AllowInsecureHttp özelliklerine sahiptir. Güvenli olmayan protokol kullandım. Bu durumda AllowInsecureHttp = true'u ayarlayabilir veya Filtreler boru hattına Https filtresi ekleyebilirsiniz.

+0

Teşekkür ederiz! AllowInsecureHttp = System.Diagnostics.Debugger.IsAttached' – boindiil

+0

ile çok fazla sayıda teşekkür ediyorum. –