Asp.net

Web API 2 身份。/Token 總是返回 404 錯誤

  • June 7, 2021

我在採用 Web API 2 身份時遇到了一些問題。在項目中。

我添加 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 發送自定義請求,結果相同。然後我檢查我的 api/Account/ExternalLogin 操作是否可用,此響應 401 狀態程式碼。我檢查引用 Owin,Microsoft.Owin 都正確。有什麼問題?我哪裡有問題?

UPS:

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

我在這個問題上弄清楚了。OAuthAuthorizationServerOptions有財產 AllowInsecureHttp。我使用了不安全的 http 協議。在這種情況下,您可以設置AllowInsecureHttp = true,也可以將 Https 過濾器添加到 Filters 管道。

我在生產環境中遇到了同樣的問題,但在本地(IIS Express)沒有。沒有什麼幫助web.config。解決方案是將明確的 NuGet 包引用添加到:Microsoft.Owin.Host.SystemWeb

引用自:https://stackoverflow.com/questions/30463511