2015-05-26 3 views
8

У меня есть некоторые проблемы с принятием Web API 2 Identity. В проекте.Идентификация Web API 2./Token Всегда возвращайте ошибку 404

добавить StartUp.cs

Как это:

using Microsoft.Owin; 
using Owin; 

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

После этого я добавить частичный класс для включения маркера авторизации:

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); 
     } 
    } 
} 

Аналогично я реализую пользователя функциональный (например, UserStore, UserManager).

Я принимаю метод «ExternalLogin» из примера и изменения.

// 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(); 
    } 

После этого я бегу мое приложение и пытался логин в приложение, как это:

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); 
     }); 

я получил ошибку 404. Я пытаюсь отправить пользовательский запрос в/Token через fiddler, и это приведет к такому же результату. Затем я проверю, что доступно действие api/Account/ExternalLogin, этот код статуса 401 ответа. Я проверяю ссылки Owin, Microsoft.Owin все правильно. В чем проблема? Где у меня проблемы?

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»? –

+0

Я использую единство для IoC. И переписать UserManager часть – CMaker

ответ

25

Я полагаю, что в этой проблеме. OAuthAuthorizationServerOptions имеет свойство AllowInsecureHttp. Я использовал небезопасный протокол http. В этом случае вы можете установить AllowInsecureHttp = true, или вы можете добавить фильтр Https в конвейер фильтров.

+0

Спасибо! У меня была такая же проблема с 'AllowInsecureHttp = System.Diagnostics.Debugger.IsAttached' – boindiil

+0

так много спасибо .... –