Web Api令牌错误405

时间:2017-12-18 23:16:04

标签: c# asp.net-web-api

我按照本教程构建了一个web api: Token Based Authentication using ASP.NET Web API 2, Owin, and Identity

我的代码完全相同,我已经检查了很多次。用户注册工作正常,但当我尝试发布" http://localhost:63927/token"它导致" HTTP错误405.0 - 方法不允许"

我不认为它是一个跨域问题,因为所有其他方法都运行良好。看看邮递员:

postman

正文用户: user

这些是我的代码

[assembly: OwinStartup(typeof(Startup))]

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();

        WebApiConfig.Register(config);

        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

        ConfigureOAuth(app);

        app.UseWebApi(config);
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new SimpleAuthorizationServerProvider()
        };

        // Token Generation
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    }
}

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

        using (AuthRepository _repo = new AuthRepository())
        {
            IdentityUser user = await _repo.FindUser(context.UserName, context.Password);

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

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        identity.AddClaim(new Claim("sub", context.UserName));
        identity.AddClaim(new Claim("role", "user"));

        context.Validated(identity);
    }
}

public class AuthRepository : IDisposable
{
    private AuthContext _ctx;

    private UserManager<IdentityUser> _userManager;

    public AuthRepository()
    {
        _ctx = new AuthContext();
        _userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(_ctx));
    }

    public async Task<IdentityResult> RegisterUser(UserModel userModel)
    {
        IdentityUser user = new IdentityUser
        {
            UserName = userModel.UserName
        };

        var result = await _userManager.CreateAsync(user, userModel.Password);

        return result;
    }

    public async Task<IdentityUser> FindUser(string userName, string password)
    {
        IdentityUser user = await _userManager.FindAsync(userName, password);

        return user;
    }

    public void Dispose()
    {
        _ctx.Dispose();
        _userManager.Dispose();
    }
}

public class UserModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

这是帐户控制器

[RoutePrefix("api/Account")]
public class AccountController : ApiController
{
    private AuthRepository _repo = null;

    public AccountController()
    {
        _repo = new AuthRepository();
    }

    // POST api/Account/Register
    [AllowAnonymous]
    [Route("Register")]
    public async Task<IHttpActionResult> Register(UserModel userModel)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        IdentityResult result = await _repo.RegisterUser(userModel);

        IHttpActionResult errorResult = GetErrorResult(result);

        if (errorResult != null)
        {
            return errorResult;
        }

        return Ok();
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            _repo.Dispose();
        }

        base.Dispose(disposing);
    }

    private IHttpActionResult GetErrorResult(IdentityResult result)
    {
        if (result == null)
        {
            return InternalServerError();
        }

        if (!result.Succeeded)
        {
            if (result.Errors != null)
            {
                foreach (string error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }
            }

            if (ModelState.IsValid)
            {
                // No ModelState errors are available to send, so just return an empty BadRequest.
                return BadRequest();
            }

            return BadRequest(ModelState);
        }

        return null;
    }
}

方法Register工作正常,没有错误

1 个答案:

答案 0 :(得分:0)

我找到了解决方案

我在前端使用html5mode所以我需要编辑web.config:

<rewrite>
  <rules>
    <rule name="AngularJS Routes" stopProcessing="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        <add input="{REQUEST_URI}" pattern="^/(api)" negate="false" /> <-- the problem
      </conditions>
      <action type="Rewrite" url="/" />
    </rule>
  </rules>
</rewrite>

我只是将negate改为false而停止导致错误。 关于“IdentityUser”问题是在上下文继承。

public class AuthContext : IdentityDbContext<IdentityUser> //this Inheritance
{
    public AuthContext()
        : base("AuthContext")
    {

    }
}

我使用的是默认的DbContext,它导致了表创建错误。