I'm using ASP.NET Web API with OAuth authorization in my project.
I have tried to decouple every tier in the solution using best practices. I have a web project which contains AngularJS files and other resources which is uploaded on www.example.com and I have another project which is protected backend web api controllers and server side stuff which is uploaded on api.example.com
It all works fine in localhost. when I publish this to production server request for "/token" is successful but requesting any action in any controller in the back-end api returns this error: "Access to XMLHttpRequest at 'http://api.example.com/someRoute' from origin 'http://www.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.".
I searched almost any active link for similar error on the internet and no answers yet for me!
I paste some of my code here from the back-end API so you can understand my approach better.
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration httpConfig = new HttpConfiguration();
UnityConfig.Register(httpConfig);
ConfigureAuth(app);
WebApiConfig.Register(httpConfig);
app.UseWebApi(httpConfig);
#region AutoMapper Init
DtoMapping.Map();
#endregion
}
}
public void ConfigureAuth(IAppBuilder app)
{
// Configure the auth context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(AuthContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
//remove this line on production
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new SimpleAuthorizationServerProvider()
};
// Token Generation
app.UseOAuthBearerTokens(OAuthServerOptions);
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
public class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
config.MapHttpAttributeRoutes();
//...
}
}
[EnableCors("*", "*", "*")]
public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
return Task.FromResult<object>(null);
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
IList<string> roleNames;
using (var _repo = new IdentityRepository())
{
var user = await _repo.FindUserAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "username or password is invalid.");
context.Rejected();
return;
}
roleNames = await _repo.GetRolesForUserAsync(user.Id);
}
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
foreach (var roleName in roleNames)
{
identity.AddClaim(new Claim(ClaimTypes.Role, roleName));
}
var props = new AuthenticationProperties(new Dictionary<string, string>
{
{
"userName", context.UserName
}
});
var ticket = new AuthenticationTicket(identity, props);
context.Validated(ticket);
}
}
So, Can anyone please help me?
Thank you for your time.
SimpleAuthorizationServerProvider. Try to remove the attribute inSimpleAuthorizationServerProviderand try again. As far as I can imagine I had the same issue and this worked for me. - SNO