C# Owin OAuth Web API身份验证ValidateClientAuthentication方法在请求时未被命中
我试图在ASP.NETWebAPI2(MVC)中实现OAuthOWIN基于令牌的身份验证。当我在控制器上应用[Authorize]注释时,请求未命中ValidateclientAuthentication,并且我收到错误“此请求的授权已被拒绝”。以下是我的代码: Startup.csC# Owin OAuth Web API身份验证ValidateClientAuthentication方法在请求时未被命中,c#,asp.net-mvc,oauth,asp.net-web-api2,owin,C#,Asp.net Mvc,Oauth,Asp.net Web Api2,Owin,我试图在ASP.NETWebAPI2(MVC)中实现OAuthOWIN基于令牌的身份验证。当我在控制器上应用[Authorize]注释时,请求未命中ValidateclientAuthentication,并且我收到错误“此请求的授权已被拒绝”。以下是我的代码: Startup.cs [assembly: OwinStartup(typeof(EY.DRA.WebAPI.Startup))] namespace EY.DRA.WebAPI { public class Startup
[assembly: OwinStartup(typeof(EY.DRA.WebAPI.Startup))]
namespace EY.DRA.WebAPI
{
public class Startup
{
public static string PublicClientId { get; private set; }
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
HttpConfiguration httpConfig = new HttpConfiguration();
//httpConfig.Formatters.Clear();
//httpConfig.Formatters.Add(new JsonMediaTypeFormatter());
//httpConfig.Formatters.JsonFormatter.SerializerSettings =
//new JsonSerializerSettings
//{
// ContractResolver = new CamelCasePropertyNamesContractResolver()
//};
//app.UseWebApi(httpConfig);
WebApiConfig.Register(httpConfig);
app.UseWebApi(httpConfig);
}
public void ConfigureOAuth(IAppBuilder app)
{
try
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(OwinAuthDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new AuthorizationServerProvider(PublicClientId),
//AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
AllowInsecureHttp = true
};
//app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
//{
// TokenEndpointPath = new PathString("/Token"),
// Provider = new AuthorizationServerProvider(PublicClientId),
// AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
// AllowInsecureHttp = true,
//});
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
}
catch(Exception ex)
{
throw ex;
}
}
//private static UserManager<IdentityUser> CreateManager(IdentityFactoryOptions<UserManager<IdentityUser>> options, IOwinContext context)
//{
// var userStore = new UserStore<IdentityUser>(context.Get<OwinAuthDbContext>());
// var owinManager = new UserManager<IdentityUser>(userStore);
// return owinManager;
//}
}
WebApiConfig.cs:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// enable elmah
config.Services.Add(typeof(IExceptionLogger), new ElmahExceptionLogger());
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
// constraint required so this route only matches valid controller names
constraints: new { controller = GetControllerNames() }
);
}
// helper method that returns a string of all api controller names
// in this solution, to be used in route constraints above
private static string GetControllerNames()
{
var controllerNames = Assembly.GetCallingAssembly()
.GetTypes()
.Where(x =>
x.IsSubclassOf(typeof(ApiController)) &&
x.FullName.StartsWith(MethodBase.GetCurrentMethod().DeclaringType.Namespace + ".Controllers"))
.ToList()
.Select(x => x.Name.Replace("Controller", ""));
return string.Join("|", controllerNames);
}
}
}
我正在应用[Authorize]属性的控制器类:
[Authorize]
public class RegisteredUserController : ApiController
{
private readonly IRegisteredUserService _regUsrServices;
#region Constructors
public RegisteredUserController()
{
_regUsrServices = new RegisteredUserService();
}
#endregion
public List<RegisteredUserDTO> GetRegisteredUser()
{
return _regUsrServices.GetRegisteredUser();
}
}
[授权]
公共类RegisteredUserController:ApiController
{
私人只读IRegisteredUserService\u regUsrServices;
#区域构造函数
公共注册控制器()
{
_regUsrServices=新的RegisteredUserService();
}
#端区
公共列表GetRegisteredUser()
{
返回_regUsrServices.GetRegisteredUser();
}
}
上述代码的问题在于,当新请求传入时(例如),执行过程会经过ConfigureOAuth(IAppBuilder app)->AppificationUserManager.Create->,然后直接转到RegisteredUserController,而无需转到AuthorizationServerProvider->ValidateClientAuthentication。
标题传递正确,我可以从IOwinContext上下文查看它。请帮助我如何点击ValidateClientAuthentication方法来验证请求
以下是我对服务器的请求在Postman中的外观:
当我发送/令牌时,我收到“不受支持的授权类型”错误:
在这个调用中,ValidateClientAuthentication被命中。请提供帮助。授权服务器的主要目的是在获得资源所有者批准的情况下向第三方客户端颁发令牌。您可以从OAuthoOptions中定义的端点获取令牌。 查看此链接以了解更多信息。
授权服务器的主要用途是在获得资源所有者批准的情况下向第三方客户端颁发令牌。您可以从OAuthoOptions中定义的端点获取令牌。 查看此链接以了解更多信息。
但ValidateClientAuthentication根本没有受到影响,令牌将如何生成以及上下文将如何验证?如果您使用GrantResourceOwnerCredentials中的GrantResourceOwnerCredentials作为密码,如果您使用客户端凭据作为GrantResourceOwnerCredentials,则它将命中ValidateClientAuthentication。但我在ValidateClientAuthentication和GrantResourceOwnerCredentials中都设置了断点,没有任何内容受到影响。您可以向服务器评论您的请求吗?我已在问题中添加了图像,请检查。但是ValidateClientAuthentication根本没有受到影响,令牌将如何生成以及上下文将如何验证?如果您使用GrantResourceOwnerCredentials中的GrantResourceOwnerCredentials作为密码,如果您使用客户端凭据作为GrantResourceOwnerCredentials,则它将命中ValidateClientAuthentication。但我在ValidateClientAuthentication和GrantResourceOwnerCredentials中都设置了断点,没有任何内容被点击。您可以向服务器评论您的请求吗?我已经在问题中添加了图像,请检查。
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
public partial class AspNetUser : IdentityUser
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public AspNetUser()
{
this.AspNetUserClaims = new HashSet<AspNetUserClaim>();
this.AspNetUserLogins = new HashSet<AspNetUserLogin>();
this.AspNetRoles = new HashSet<AspNetRole>();
}
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<AspNetUser> manager, string authenticationType)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
// Add custom user claims here
return userIdentity;
}
public string Id { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
public string SecurityStamp { get; set; }
public string PhoneNumber { get; set; }
public bool TwoFactorEnabled { get; set; }
public Nullable<System.DateTime> LockoutEndDateUtc { get; set; }
public int AccessFailedCount { get; set; }
public string UserName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<AspNetUserClaim> AspNetUserClaims { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<AspNetUserLogin> AspNetUserLogins { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<AspNetRole> AspNetRoles { get; set; }
}
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// enable elmah
config.Services.Add(typeof(IExceptionLogger), new ElmahExceptionLogger());
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
// constraint required so this route only matches valid controller names
constraints: new { controller = GetControllerNames() }
);
}
// helper method that returns a string of all api controller names
// in this solution, to be used in route constraints above
private static string GetControllerNames()
{
var controllerNames = Assembly.GetCallingAssembly()
.GetTypes()
.Where(x =>
x.IsSubclassOf(typeof(ApiController)) &&
x.FullName.StartsWith(MethodBase.GetCurrentMethod().DeclaringType.Namespace + ".Controllers"))
.ToList()
.Select(x => x.Name.Replace("Controller", ""));
return string.Join("|", controllerNames);
}
}
}
[Authorize]
public class RegisteredUserController : ApiController
{
private readonly IRegisteredUserService _regUsrServices;
#region Constructors
public RegisteredUserController()
{
_regUsrServices = new RegisteredUserService();
}
#endregion
public List<RegisteredUserDTO> GetRegisteredUser()
{
return _regUsrServices.GetRegisteredUser();
}
}