Following is the code. When I make an separate request using postman to "/token" it works. But when I call from a client side code, it fails with 400 bad request. When I debug I can see that the "GrantResourceOwnerCredentials" method is not getting hit. Any idea?
Client Code
return this.$http({
url: this.config.remoteUri.account.login,
method: "POST",
data: { UserName: user.name, Password: user.password, grant_type: "password" },
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function (data, status, headers, config) {
// $scope.persons = data; // assign $scope.persons here as promise is resolved here
}).error(function (data, status, headers, config) {
// $scope.status = status;
});
Startup.cs
public class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app)
{
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(20),
Provider = new ActiveDirectoryAuthorizationProvider()
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
}
}
Webapi Config
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
}
Authorization Filter
public class ActiveDirectoryAuthorizationProvider : OAuthAuthorizationServerProvider
{
public override Task MatchEndpoint(OAuthMatchEndpointContext context)
{
if (context.IsTokenEndpoint && context.Request.Method == "OPTIONS")
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "authorization" });
context.RequestCompleted();
return Task.FromResult(0);
}
return base.MatchEndpoint(context);
}
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[] { "*" });
First things first: Origin header has to be set on your outgoing request (OPTIONS+POST)
I've seen this implementation of the filter in other threads but here is mine which is in fact working for me - local and production server:
public override Task MatchEndpoint(OAuthMatchEndpointContext context)
{
if (context.IsTokenEndpoint && context.Request.Method == "OPTIONS")
{
if (!context.OwinContext.Response.Headers.Keys.Contains("Access-Control-Allow-Origin"))
context.OwinContext.Response.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Origin", new[] { ConfigurationManager.AppSettings["allowedOrigin"] });
if (!context.OwinContext.Response.Headers.Keys.Contains("Access-Control-Allow-Headers"))
context.OwinContext.Response.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Headers", new[] { "Accept", "Content-Type", "Authorization", "Cache-Control", "Pragma", "Origin" });
if (!context.OwinContext.Response.Headers.Keys.Contains("Access-Control-Allow-Methods"))
context.OwinContext.Response.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Methods", new[] { "GET", "POST", "PUT", "DELETE", "OPTIONS" });
context.MatchesTokenEndpoint();
context.RequestCompleted();
return Task.FromResult<object>(null);
}
return base.MatchEndpoint(context);
}
If you still have issues please respond with more details. Please note that AppendCommaSeparatedValues is required for this to work under IE and Edge
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.