Keycloak angular Нет заголовка «Access-Control-Allow-Origin»

Я интегрировал keycloak с угловым приложением. По сути, и внешний, и внутренний интерфейс находятся на разных серверах. Бэкэнд-приложение работает на apache tomcat 8. Фронтенд-приложение работает в папке приветственного содержимого JBoss.

Конфигурация Angular

angular.element(document).ready(function ($http) {
    var keycloakAuth = new Keycloak('keycloak.json');
    auth.loggedIn = false;
    keycloakAuth.init({ onLoad: 'login-required' }).success(function () {
        keycloakAuth.loadUserInfo().success(function (userInfo) {
            console.log(userInfo);  
        });
        auth.loggedIn = true;
        auth.authz = keycloakAuth;
        auth.logoutUrl = keycloakAuth.authServerUrl + "/realms/app1/protocol/openid-connect/logout?redirect_uri=http://35.154.214.8/hrms-keycloak/index.html";
        module.factory('Auth', function() {
            return auth;
        });
        angular.bootstrap(document, ["themesApp"]);
    }).error(function () {
            window.location.reload();
        });

});
module.factory('authInterceptor', function($q, Auth) {
    return {
        request: function (config) {
            var deferred = $q.defer();
            if (Auth.authz.token) {
                Auth.authz.updateToken(5).success(function() {
                    config.headers = config.headers || {};
                    config.headers.Authorization = 'Bearer ' + Auth.authz.token;
                    deferred.resolve(config);
                }).error(function() {
                        deferred.reject('Failed to refresh token');
                    });
            }
            return deferred.promise;
        }
    };
});
module.config(["$httpProvider", function ($httpProvider)  {
    $httpProvider.interceptors.push('authInterceptor');
}]);

Заголовок запроса

Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization
Access-Control-Request-Method:GET
Connection:keep-alive
Host:35.154.214.8:8080
Origin:http://35.154.214.8
Referer:http://35.154.214.8/accounts-keycloak/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36

Ошибка в веб-консоли.

XMLHttpRequest cannot load http://35.154.214.8:8080/company/loadCurrencyList. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://35.154.214.8' is therefore not allowed access.

Фильтр Cors на серверной части

@Component
public class CORSFilter implements Filter {
    static Logger logger = LoggerFactory.getLogger(CORSFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "*");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");
        chain.doFilter(request, response);
    }

    public void destroy() {
    }
}

person boycod3    schedule 12.07.2017    source источник
comment
Включили ли вы CORS на сервере, на котором работает бэкенд? ?   -  person urbz    schedule 12.07.2017
comment
Ага. проверьте вопрос еще раз. Вопрос обновлен. кажется, токен не проходит.   -  person boycod3    schedule 12.07.2017
comment
@boycod3 Вы решили проблему?   -  person Christian    schedule 31.07.2017


Ответы (11)


Я боролся с KeyCloak и CORS и всем этим около двух недель, и это мое решение (для keycloak 3.2.1):

Its all about configuring KeyCloak server. It seems to be, that WebOrigin of your Realm needs to be

*
Only one origin "*".

Вот и все, что мне было нужно.

Если вы вводите свой сервер как WebOrigin, начинаются проблемы. Когда вы вызываете keycloak.init в JavaScript, keycloak не генерирует заголовки CORS, поэтому вам нужно настроить их вручную, и как только вы это сделаете, и вызвать keycloak.getUserInfo после успешной инициализации — вы получите двойные заголовки CORS, что не разрешается.

Где-то глубоко внутри списков рассылки keycloak указано, что вам нужно установить enable-cors=true в вашем keycloak.json, но на keycloak.gitbooks.io об этом ничего нет. Так что похоже не правда.

Они также не упоминают CORS при описании адаптеров JavaScript и Node.Js, и я не знаю почему, кажется, это вообще не важно.

Также кажется, что вам не следует трогать конфигурацию WildFly для предоставления заголовков CORS.

Кроме того, CORS в OIDC — это специальная функция KeyCloak (а не ошибка).

Надеюсь, этот ответ послужит вам хорошо.

person subrob sugrobych    schedule 01.08.2017
comment
enable-corsописан и объяснен в документации Keycloak в разделе адаптеров Java. - person Sébastien Blanc; 22.09.2017
comment
Делать это в производстве ужасно и противоречит причине использования keycloak в первую очередь (например, безопасность) - person Phil; 03.08.2018
comment
enable-cors описан и объяснен в документации Keycloak в разделе адаптеров Java в течение 2 лет периодических экспериментов. Я до сих пор не могу с уверенностью определить, делает ли enable-cors что-либо вообще. Одна вещь, которую он определенно никогда не делал нигде, где я пробовал: включить заголовки CORS. - person tekHedd; 19.12.2018
comment
Это такая боль - person DJ MERKEL; 30.03.2020
comment
Я использую Keycloak 10.0.1. Я добавил + для клиента Web Origins, и он работал в моем приложении Angular 9.1. - person Richard K. Campion; 21.05.2020

Важно отметить, что установка вашего веб-источника на «*» открывает зияющую дыру в безопасности. Это позволяет любому сценарию из любого домена выполнять запросы от имени пользователя в браузере этого пользователя.

Всякий раз, когда вы обнаруживаете, что отключаете функцию безопасности таким образом, вам нужно подумать, почему эта функция безопасности существует.

См. раздел 8.1.1 документации Keycloak.

person GuyPaddock    schedule 13.01.2018
comment
Я попытался установить URL-адрес и даже попробовал *. Я все еще получаю ту же ошибку. Есть идеи? Я получаю доступ к своей серверной конечной точке (защищенной keycloak) с помощью ajax - person pvpkiran; 24.02.2020

Решение, которое сработало для меня, заключалось в настройке URL-адреса веб-происхождения (моего клиента, а не области), например: http://localhost:3000/ на http://localhost:3000 (обратите внимание на отсутствие / в конце). Таким образом, вы не открываете его для всех URL-адресов, используя *.

person Juan Espinosa    schedule 28.02.2019
comment
У меня была такая же проблема с веб-источником, отличным от локального хоста, и удаление косой черты также сработало для меня. Спасибо - person Franck LEVEQUE; 07.08.2020
comment
Это решение также сработало для меня. Это должен быть принятый ответ. - person Micah Parks; 04.03.2021

У меня была та же проблема, и (по крайней мере) для Keycloak Server версии 8.0.1 вы можете добавить «+» в качестве ввода в поле «Веб-происхождение», что кажется лучшим выбором.

Эффект «+» должен быть таким же, как добавление (см. снимок экрана ниже) «http://localhost:4200» как « Запись Web Origins.

Вот что говорит всплывающая подсказка поля «Веб-источники»:

"Разрешенные источники CORS. Чтобы разрешить все источники "Действительных URI перенаправления", добавьте '+'. Чтобы разрешить все источники, добавьте '*'." (см. снимок экрана ниже)

Настройки Web Origin клиента Keycloak

person Nils Heumer    schedule 22.01.2020

У меня была такая же ошибка CORS. Новое в KeyCloak. Пробовал установить веб-источник на «*», «+» и определенные URL-адреса. Ничего не сработало. Пока я не изменил «Тип доступа» в настройках клиента на общедоступный. Тогда оба варианта установки веб-происхождения для определенного URL-адреса и + работали. Так как установка * не защищена, не пробовал.

Когда тип доступа установлен на конфиденциальный, он снова начал выдавать ошибку CORS. Я пробовал поток авторизации с PKCE (поток кода).

Использование версии 10.0.2.

Скриншот настройки, которая сработала:

введите описание изображения здесь

person meDev    schedule 12.06.2020
comment
Вы решили проблему с конфиденциальным типом доступа? У меня такая же проблема, но я не хочу использовать тип общего доступа. может ли это быть связано с политикой использования файлов cookie того же сайта? - person fjahan; 02.05.2021

Вы дали ответ на свой вопрос, добавив WebOrigin как * на уровне клиента (НЕ на уровне области!), Что сработало для вас, но в моем случае это не сработало. На самом деле, удаление * было для меня трюком, потому что KC дважды отправлял заголовки CORS - удаляя его, разделив его до одного раза...

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

С чем мы все согласны, так это с тем, что документация KC, по крайней мере, очень плохая.

Написано для чайников, но.... мы не чайники, и предмет не...

Это не объясняет технические детали. Например, каковы ответы от конечных точек. Поиск в сети (две недели) дает немного - но почему это не указано в документации?

Один пример. Но у меня несколько...

Можем ли мы помочь с документацией?

person Dutchboy    schedule 22.09.2017
comment
Конечно, вы можете помочь, все это с открытым исходным кодом, отправляйте свои запросы на вытягивание на github.com/keycloak/keycloak-documentation , мы будем более чем рады просмотреть его. - person Sébastien Blanc; 22.09.2017
comment
полностью согласен с @SébastienBlanc, жаловаться на что-то не становится лучше. - person Steven Ferrer; 22.07.2018

У меня была та же проблема, и в моем случае это было вызвано использованием объекта параметров в создании адаптера js keycloak, где URL-адрес сервера аутентификации был ошибочно установлен на http вместо https:

const keycloak = Keycloak({
    url: 'http://my-keycloak-auth-server/auth',
    realm: 'myRealm',
    clientId: 'myClient'
});

но правильно было

const keycloak = Keycloak({
    url: 'https://my-keycloak-auth-server/auth',
    realm: 'myRealm',
    clientId: 'myClient'
});
person jschmuecking    schedule 21.08.2019

Это довольно старый вопрос, но я все равно отвечаю на него. Это может помочь кому-то. На странице администратора keycloak перейдите на clients->your client. Там вы можете увидеть ниже поле под названием web origins. Там вы вводите свой URL-адрес, и ваша проблема будет решена.

введите здесь описание изображения

person kaushik    schedule 15.12.2020

Столкнулся с той же проблемой при работе с Angular 6, Spring Boot для веб-служб REST и Keycloak.

Адрес Keycloak: KEYCLOAK
Адрес приложения Angular 6: ANGULAR_APP
Две REST WS, защищенные с помощью Keycloak и Spring Autoconfiguration: AA, BB

Поток был: запрос приложения Angular (GET) AA, запрос AA (GET) BB

Ошибка использования XMLHttpRequest была примерно такой: Невозможно загрузить AA. Ответ на предварительный запрос не проходит проверку управления доступом: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Таким образом, источник «ANGULAR_APP» не имеет доступа.

При использовании Observable из Angular это было: Не удалось загрузить AA: перенаправление с «BB» на «KEYCLOAK» было заблокировано политикой CORS: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Таким образом, Origin «ANGULAR» не имеет доступа.

Пробовал с веб-источниками: * без решения

Никогда не знал, почему Keycloak делал это перенаправление, которое вызывало проблему

Проблема волшебным образом исчезла, когда я переключил безопасность в службе AA с Keycloak + Autoconfigure на Keycloak + Spring Security в соответствии с: https://developers.redhat.com/blog/2017/05/25/easily-secure-your-spring-boot-applications-with-keycloak/

Из-за этого потерял много дней сна. Просто оставлю это на случай, если кто-то столкнется с чем-то подобным.

person Galo    schedule 08.08.2018

Я добавляю эту строку при инициализации...

this.keycloakAuth.init({ onLoad: 'требуется вход', поток: 'неявный' })

person Felipe Jansen    schedule 06.12.2020

Боролся с аналогичной ошибкой с keycloak-js хотя и не в Angular: я смог успешно авторизоваться с кодом из документации:

keycloak.init({
  onLoad: 'login-required',
}).then(function(authenticated) {
  alert(authenticated ? 'authenticated' : 'not authenticated');
}).catch(function() {
  alert('failed to initialize');
});

Но последовательные вызовы (в моем случае keycloak.loadUserProfile(), вызов конечной точки account) приведут к ошибкам CORS.

Позже я узнал, что неправильно подстроил свой код, так что последовательные вызовы имели условия гонки с init! Задним числом очевидно, но..

TLDR; Если вы вызываете конечные точки keycloak до завершения вызова init, в ответе не будет заголовков CORS, и вы получите ошибку CORS! Это просто означает, что вы не авторизованы.

person oskarth    schedule 10.07.2021