2017-02-10 1 views
0

키 클로크와 같은 오픈 소스 사용자 관리 서비스를 이용하려고합니다. 키 클록에 의해 보안 된 REST 엔드 포인트로 HTTP 요청을 보낼 angularJs 앱을 작성합니다. 백엔드에서 스프링 부트를 사용하고 있습니다. 엔드 포인트를 호출하고 승인되지 않은 출처에서 오는 요청을 차단해야하므로 가능한 결과를 얻지 못했습니다. keycloak (스프링 부트) REST 엔드 포인트를 인증하지 않습니다.

내가
  • keycloak with angular and spring boot
  • 사용자가 호출 REST 엔드 포인트 구성

    2. Github link to keycloak example

    컨트롤러

      을 따라 두 개의 링크입니다.

      server.port = 8090 
      
      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 = 111-1111-111-111 
      keycloak.use-resource-role-mappings = true 
      keycloak.cors= true 
      
      keycloak.securityConstraints[0].securityCollections[0].name = spring secured api 
      keycloak.securityConstraints[0].securityCollections[0].authRoles[0] = user 
      keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /api 
      
      keycloak.securityConstraints[0].securityCollections[1].name = insecure stuff 
      keycloak.securityConstraints[0].securityCollections[1].authRoles[0] = user 
      keycloak.securityConstraints[0].securityCollections[1].patterns[0] = /check 
      

      에 대한 상시 관측소와

      @RequestMapping(value = "/api/getSample") 
      public test welcome() { 
          return new test("sample"); 
      } 
      
      @RequestMapping(value = "/check/test") 
      public test welcome2() { 
          return new test("test"); 
      } 
      

      봄 부팅 응용 프로그램은

      @SpringBootApplication 
      public class Application 
      { 
          public static void main(String[] args) 
          { 
           SpringApplication.run(Application.class, args); 
          } 
      
          @Bean 
          public FilterRegistrationBean corsFilter() { 
           UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
           CorsConfiguration config = new CorsConfiguration(); 
           config.setAllowCredentials(true); 
           config.addAllowedOrigin("*"); 
           config.addAllowedHeader("*"); 
           config.addAllowedMethod("*"); 
           source.registerCorsConfiguration("/api/*", config); 
      
           FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); 
           bean.setOrder(0); 
           return bean; 
          } 
      } 
      

      응용 프로그램 특성 파일이 테스트 케이스

      1. 로그인하지 않고 REST 호출을 만들기가 있습니다.에 이 경우 나는 할 수있다. 결과를 다시 얻으십시오. 이 경우가 아니어야하며 차단해야합니다 (401 오류 발생).

      2. 로그인 할 때 REST 호출하기. api/getSample을 호출 할 수 있으며 올바른 동작입니다. 내가 검사/시험 호출 할 때 그러나 나는 XMLHttpRequest cannot load http://localhost:8090/check/test. Response to preflight request doesn't pass access control check: 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 403.

    답변

    0

    을 얻을 당신은 당신의 pom.xml에 봄 부팅 Keycloak 어댑터 의존성을 추가하지 않았습니다.

    2. 당신은 내가 당신의 시험과 같은 방법을 정확하게 모르는/검사 (만/API에 대한)

    <dependency> 
         <groupId>org.keycloak</groupId> 
         <artifactId>keycloak-spring-boot-adapter</artifactId> 
         <version>${keycloak.version}</version> 
        </dependency> 
    
    +0

    ofcourse – krs8888

    1

    1)

    에 대한 CORS를 구성,하지만하지 않은 시스템이 당신이 아직 로그인되어 있다고 생각할 수 있습니까? 쿠키를 삭제하여 액세스 토큰이 저장되지 않도록 할 수 있습니다.

    다른 옵션은 스프링 부트가 Keycloak 어댑터를 인식하지 못하여 액세스를 보호하지 못하는 것일 수 있습니다. 주로 keycloak-spring-boot-adapterkeycloak-tomcat8-adapter 종속성 (more details here)을 추가하여 어댑터를 구성합니다. CORS가 제대로 구성되지 않은 것처럼

    2)

    것 같습니다. 구성 (more details here)에 대한 구현을 고려해 볼 수 있습니다.

    @Bean 
    FilterRegistrationBean corsFilter(
         @Value("${tagit.origin:http://localhost:9000}") String origin) { 
        return new FilterRegistrationBean(new Filter() { 
         public void doFilter(ServletRequest req, ServletResponse res, 
              FilterChain chain) throws IOException, ServletException { 
          HttpServletRequest request = (HttpServletRequest) req; 
          HttpServletResponse response = (HttpServletResponse) res; 
          String method = request.getMethod(); 
          // this origin value could just as easily have come from a database 
          response.setHeader("Access-Control-Allow-Origin", origin); 
          response.setHeader("Access-Control-Allow-Methods", 
            "POST,GET,PUT,DELETE"); 
          response.setHeader("Access-Control-Max-Age", Long.toString(60 * 60)); 
          response.setHeader("Access-Control-Allow-Credentials", "true"); 
          response.setHeader(
            "Access-Control-Allow-Headers", 
            "Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization"); 
          if ("OPTIONS".equals(method)) { 
           response.setStatus(HttpStatus.OK.value()); 
          } 
          else { 
           chain.doFilter(req, res); 
          } 
         } 
    
         public void init(FilterConfig filterConfig) { 
         } 
    
         public void destroy() { 
         } 
        }); 
    } 
    
    관련 문제