asp.net - Web API 2 身份./Token 总是返回404错误

标签 asp.net asp.net-web-api2 asp.net-identity-2

我在采用 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);
            }
        }
}

之后,我添加部分类以启用 token 授权:

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 错误。我尝试通过 fiddler 向/Token 发送自定义请求,这会得到相同的结果。然后我检查我的 api/Account/ExternalLogin 操作是否可用,此响应 401 状态代码。我检查引用 Owin、Microsoft.Owin 都正确。有什么问题?我哪里有问题?

更新:

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协议(protocol)。在这种情况下,您可以设置 AllowInsecureHttp = true,或者您可以将 Https 过滤器添加到 Filters 管道。

关于asp.net - Web API 2 身份./Token 总是返回404错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30463511/

相关文章:

c# - 从 FQDN 获取域名?

c# - WebAPI 确保所有响应都自动进行 UTF8 编码,以避免不必要的反弹和引述

asp.net - 身份验证后手动将属性添加到请求正文

c# - 在没有 Entity Framework 的情况下使用带有 OData 提要 C# 的存储过程进行自定义分页

c# - Entity Framework 6 Code first 3级子表中的一对多关系

c# - 为什么 HttpContext.Current 为空?

javascript - 获取asp :Button Text into a JavaScript function

c# - 代码隐藏的 ASP.NET 文件上传的生命周期是多少?

asp.net - .Net 身份 2 与 3

c# - 转换/修改 asp.net identity 2 中的声明