2016-12-14 5 views
9

Я использую keycloak для обеспечения моего отдыха. Я имею в виду учебник, приведенный here. Я создал остальное и переднюю часть. Теперь, когда я добавляю keycloak на бэкэнд, я получаю ошибку CORS, когда мой передний конец вызывает api call.keycloak CORS фильтр весенний ботинок

Application.java файл в весенней загрузке выглядит как

@SpringBootApplication 
public class Application 
{ 
    public static void main(String[] args) 
    { 
     SpringApplication.run(Application.class, args); 
    } 

    @Bean 
    public WebMvcConfigurer corsConfiguration() { 
     return new WebMvcConfigurerAdapter() { 
      @Override 
      public void addCorsMappings(CorsRegistry registry) { 
       registry.addMapping("/api/*") 
         .allowedMethods(HttpMethod.GET.toString(), HttpMethod.POST.toString(), 
           HttpMethod.PUT.toString(), HttpMethod.DELETE.toString(), HttpMethod.OPTIONS.toString()) 
         .allowedOrigins("*"); 
      } 
     }; 
    } 
} 

Свойство keycloak в application.properties файл выглядит как

keycloak.realm = demo 
keycloak.auth-server-url = http://localhost:8080/auth 
keycloak.ssl-required = external 
keycloak.resource = tutorial-backend 
keycloak.bearer-only = true 
keycloak.credentials.secret = 123123-1231231-123123-1231 
keycloak.cors = true 
keycloak.securityConstraints[0].securityCollections[0].name = spring secured api 
keycloak.securityConstraints[0].securityCollections[0].authRoles[0] = admin 
keycloak.securityConstraints[0].securityCollections[0].authRoles[1] = user 
keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /api/* 

Образец REST API, который я называю

@RestController 
public class SampleController {  
    @RequestMapping(value ="/api/getSample",method=RequestMethod.GET) 
    public string home() { 
     return new string("demo"); 
    }   
} 

свойства keyclayak.json переднего края включают

{ 
    "realm": "demo", 
    "auth-server-url": "http://localhost:8080/auth", 
    "ssl-required": "external", 
    "resource": "tutorial-frontend", 
    "public-client": true 
} 

Ошибка CORS, что я получаю

XMLHttpRequest cannot load http://localhost:8090/api/getSample. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. The response had HTTP status code 401. 
+1

Возможно, вы зададите конкретный вопрос. В противном случае вы можете получить ответы, которые не подходят для вас. – Alexander

+0

Можете ли вы предоставить весь стек? –

+0

На стороне сервера нет ошибок. Следовательно, нет трассировки стека. Ошибка i на стороне клиента, когда мое приложение angularJS делает вызов остальным, я получаю ошибку CORS на консоли браузера – krs8888

ответ

0

Когда ваш клиент отсылая заголовок аутентификации, вы не можете использовать allowedOrigins ("*"). Вы должны настроить определенный URL-адрес происхождения.

+1

Это не работает. Я изменил allowedOrigins на URL-адрес, с которого работает мой клиент. В моем проекте он работает на localhost: 9000. Даже после изменения, что я все еще получаю ошибку – krs8888

2

Попробуйте создать свой бобы CORS, как в моем примере. Недавно я прошел то же самое (чтобы заставить CORS работать), и это был кошмар, потому что поддержка SpringBoot CORS в настоящее время не такая надежная или простая, как MVC CORS.

@Bean 
public FilterRegistrationBean corsFilter() { 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
    CorsConfiguration config = new CorsConfiguration(); 
    config.setAllowCredentials(true); 
    config.addAllowedOrigin("*"); 
    config.addAllowedHeader("*"); 
    config.addAllowedMethod("*"); 
    source.registerCorsConfiguration("/**", config); 

    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); 
    bean.setOrder(0); 
    return bean; 
} 

Это, как я поставил его принять любое происхождение приложения широко, но если изменить несколько параметров, которые вы должны быть в состоянии повторить то, что вы хотите. то есть. если вы хотите добавить только те методы, о которых вы упомянули, соедините addAllowedMethod(). Допустимое происхождение будет одинаковым, и тогда ваш addMapping("/api/*") станет source.registerCorsConfiguration("/api/*", config);.

Edit:

Spring Data Rest and Cors

Посмотрите на это. Себастьян находится в команде разработчиков Spring, так что это примерно так же хорошо, как вы получите официальный ответ.

+0

@ krs8888, дайте мне знать, если это сработает для вас. –

+0

уверен, что я дам вам знать, когда я попробую, как только я вернусь из отпуска на следующей неделе – krs8888

+0

, меняя свою фасоль на то, что вы опубликовали, не работал. Я думаю, что плохо попробуйте использовать весенний mvc и не использовать весенний ботинок вообще – krs8888

1

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

Реакция Джона Уэста похожа на недавние проблемы, с которыми я столкнулся с Spring и CORS, однако я бы посоветовал вам изучить, в какую реализацию ссылается пример весны, потому что их два. Spring Security и Spring MVC Annotations. Обе эти реализации работают независимо друг от друга и не могут быть объединены.

При использовании подхода, основанного на фильтрах, как вы (даже сварили), ключ должен был установить разрешить учетные данные в true, чтобы заголовки аутентификации были отправлены браузером через домены. Я бы также посоветовал использовать предложенный выше метод полного кода, поскольку это позволит вам создать гораздо более настраиваемое веб-приложение для развертывания в нескольких доменах или средах путем вставки свойств или реестра служб.

+0

Хорошая точка в аннотациях. Я отредактировал свой ответ, чтобы включить ссылку на аналогичный вопрос, на котором активно работал инженер Spring. Если у вас была такая же проблема, я предполагаю, что вы натолкнулись на нее в какой-то момент. –

1

Access-Control-Allow-Origin заголовок должен быть установлен серверным приложением в заголовке запроса Origin, указанном в запросе серверному приложению. Обычно браузеры задают заголовок Origin в запросе, когда они ощущают запрос на перекрестный поиск. И они ожидают заголовок Access-Control-Allow-Origin в ответ на это.

Теперь, для keycloak, я боролся с той же проблемой. Глядя на this, похоже, что keycloak не добавляет заголовок Access-Control-Allow-Origin в случае ошибки. Однако для меня он не добавлял этот заголовок в ответ даже в случае ответа на успех.

Просмотрев код и добавив точки останова, я заметил, что webOrigin для клиентского объекта не был заполнен заголовком Origin, даже если он был передан, и, следовательно, CORS не добавлял заголовок ответа управления доступом.

Я был в состоянии получить работу, добавив следующую строку кода непосредственно перед CORS построить вызов:

client.addWebOrigin(headers.getRequestHeader("Origin").get(0)); 

до:

Cors.add(request, Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).auth().allowedOrigins(client).allowedMethods("POST").exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS).build(); 

После того, как я построил код с помощью этого изменения и начал работу с сервером, я начал получать три заголовка ответа на управление доступом:

Access-Control-Expose-Headers: Access-Control-Allow-Methods 
Access-Control-Allow-Origin: http://localhost:9000 
Access-Control-Allow-Credentials: true 

Я используя тип гранта учетных данных клиента; поэтому я добавил его только в buildClientCredentialsGrant по адресу TokenEndpoint.java#L473.

Мне еще нужно сделать еще несколько дайвинга кода, чтобы точно сказать, что это ошибка для ответов об успехе, и найти лучшее место, чтобы установить это на клиентском объекте в коде keyclayak (например, где клиентский объект строится)

Приглашаем вас попробовать.

ОБНОВЛЕНИЕ:
Я забираю это обратно. Я перерегистрировал своего клиента в keycloak с корневым URL как http://localhost:9000 (который является моим портом приложений внешнего интерфейса), и я начал получать правильные заголовки ответов на управление доступом. Надеюсь, это поможет вам.

Смежные вопросы