简体   繁体   English

Owin Bearer令牌不适用于WebApi

[英]Owin Bearer Token Not Working for WebApi

I have gone through loads of documentation on this, My google search shows that I've visited all the links on the first page 我已经浏览了大量文档,我的谷歌搜索显示我访问了第一页上的所有链接

Problem Token Generation works fine. 问题令牌生成工作正常。 I configured it with a custom provider as such: 我使用自定义提供程序配置它:

    public void ConfigureOAuth(IAppBuilder app)
    {
        var usermanager = NinjectContainer.Resolve<UserManager>(); 
        app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new AppOAuthProvider(usermanager)
        });
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    }

However when I call a protected URL and pass the bearer token, I always get: 但是,当我调用受保护的URL并传递持有者令牌时,我总是得到: 令牌请求

How do I diagnose or fix the problem. 我如何诊断或解决问题。 If possible, how can I do the token validation myself 如果可能,我如何自己进行令牌验证

UPDATE Here is my AppOAuthProvider. 更新这是我的AppOAuthProvider。 Both Methods are called when I'm trying to mint a token but not when I'm trying to access a protected resource 当我尝试使用令牌时,会调用这两种方法,但在我尝试访问受保护资源时则不会

public class AppOAuthProvider : OAuthAuthorizationServerProvider
{
    private UserManager _user;
    public AppOAuthProvider(UserManager user)
    {
        _user = user;
    }
    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
    }

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

        //Get User Information
        var getUser = _user.FindUser(context.UserName);
        if (getUser.Status == StatusCode.Failed)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return Task.FromResult<object>(null);
        }

        var user = getUser.Result;

        //Get Roles for User
        var getRoles = _user.GetRoles(user.UserID);
        if (getRoles.Status == StatusCode.Failed)
        {
            context.SetError("invalid_grant", "Could not determine Roles for the Specified User");
        }

        var roles = getRoles.Result;

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

        foreach (var role in roles)
        {
            identity.AddClaim(new Claim(ClaimTypes.Role, role));
        }

        context.Validated(identity);

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

UPDATE 2: Here is my Account Controller 更新2:这是我的账户控制员

[RoutePrefix("api/auth/account")]
public class AccountController : ApiController
{
    private UserManager _user;
    public AccountController(UserManager user)
    {
        _user = user;
    }

    [Authorize]
    [HttpGet]
    [Route("secret")]
    public IHttpActionResult Secret()
    {
        return Ok("Yay! Achievement Unlocked");
    }
}

UPDATE 3: Here is my Startup.cs 更新3:这是我的Startup.cs

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseNinjectMiddleware(NinjectContainer.CreateKernel);
        app.UseNinjectWebApi(GlobalConfiguration.Configuration);
        GlobalConfiguration.Configure(WebApiConfig.Register);
        ConfigureOAuth(app);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(GlobalConfiguration.Configuration);
        app.UseWelcomePage();
    }
}

You must configure the OAuth authorization server and OAuth bearer authentication before call UseWebApi on IAppBuilder. 您必须在IAppBuilder上调用UseWebApi之前配置OAuth授权服务器和OAuth承载身份验证。 The following is from my program. 以下是我的计划。

    public void Configuration(IAppBuilder app)
    {
        app.UseFileServer(new FileServerOptions()
        {
            RequestPath = PathString.Empty,
            FileSystem = new PhysicalFileSystem(@".\files")
        });

        // set the default page
        app.UseWelcomePage(@"/index.html");

        ConfigureAuth(app);

        HttpConfiguration config = new HttpConfiguration();

        config.Routes.MapHttpRoute
        (
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional } 
        );

        config.Formatters.Clear();
        config.Formatters.Add(new JsonMediaTypeFormatter());
        config.Formatters.JsonFormatter.SerializerSettings =
        new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };

        app.UseCors(CorsOptions.AllowAll);
        app.UseWebApi(config);


    }

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

        app.UseOAuthAuthorizationServer(oAuthServerOptions);
        app.UseOAuthBearerAuthentication
        (
            new OAuthBearerAuthenticationOptions 
            {
                Provider = new OAuthBearerAuthenticationProvider()
            }
        );
    }
    HttpConfiguration config = new HttpConfiguration();
app.UseNinjectMiddleware(NinjectContainer.CreateKernel);
app.UseNinjectWebApi(GlobalConfiguration.Configuration);
ConfigureOAuth(app);
WebApiConfig.Register(config);
//GlobalConfiguration.Configure(WebApiConfig.Register);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
// app.UseWebApi(GlobalConfiguration.Configuration);
app.UseWebApi(config);
app.UseWelcomePage();

I tried this with ur sample application on github and it worked 我在github上用你的示例应用程序尝试了这个并且它工作了

In your provider you have to: 在您的提供商中,您必须:

public override ValidateClientAuthentication(OAuthClientAuthenticationContext context)
{
    //test context.ClientId
    //if you don't care about client id just validate the context
    context.Validated();
}

The reason for this is that if you don't override ValidateClientAuthentication and validate the context, it is assumed as rejected and you'll always get that error. 这样做的原因是,如果您不覆盖ValidateClientAuthentication并验证上下文,则假定它被拒绝,您将始终得到该错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM