Почему ошибка CORS «Ответ на предварительный запрос не проходит проверку контроля доступа»? - PullRequest
0 голосов
/ 27 октября 2018

Я использую ASP.NET Web API с авторизацией OAuth в моем проекте.

Я пытался отделить каждый уровень решения, используя лучшие практики. У меня есть веб-проект, который содержит файлы AngularJS и другие ресурсы, который загружен на www.example.com, и у меня есть другой проект, который защищен бэкэнд-контроллерами веб-API и серверными компонентами, который загружен на api.example.com

В localhost все отлично работает. когда я публикую это на производственном сервере, запрос на "/ token" будет успешным, но запрос любого действия в любом контроллере в интерфейсе API сервера возвращает эту ошибку: "Доступ к XMLHttpRequest в« http://api.example.com/someRoute' от источника »http://www.example.com' был заблокирован политикой CORS: Ответ на предполётный запрос не проходит проверку контроля доступа: Нет 'Access-Control-Allow Заголовок -Origin 'присутствует на запрашиваемом ресурсе. ".

Я искал почти любую активную ссылку на подобную ошибку в Интернете, и пока для меня нет ответов!

Я вставляю сюда часть своего кода из внутреннего API, чтобы вы могли лучше понять мой подход.

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);

    }
}

Итак, кто-нибудь может мне помочь?

Спасибо за ваше время.

1 Ответ

0 голосов
/ 01 января 2019

На случай, если кому-то интересно, вот как я решил эту проблему:

Речь шла не о том, чтобы не устанавливать политику cors в веб-интерфейсе asp.net (как я уже говорил, я делал то, что предлагал веб-сайт Microsoft docs .)

Проблема заключалась в том, что IIS не был настроен для обработки методов глагола OPTION! и поскольку в запросе перед полетом использовался метод OPTION, он всегда получал 404 не найден (отказ от веб-сервера), следовательно, ошибка.

Я должен упомянуть, что до сих пор я не знаю, почему «/ token» работал до настройки веб-сервера и почему контроллеры не реагировали так же!

но, так или иначе, проблема просто так решена. Надеюсь, это поможет!

...