keycloak(spring boot)不验证REST端点

时间:2017-02-10 06:44:36

标签: java spring rest spring-boot keycloak

我正在尝试使用像keycloak这样的开源用户管理服务。构建一个angularJs应用程序,它将发送HTTP请求到由keycloak保护的REST端点。我在后端使用弹簧靴。我能够调用端点并获得不可能的结果,因为它应该阻止来自未授权源的请求。

这是我遵循的两个链接

  1. keycloak with angular and spring boot
  2. 2。Github link to keycloak example

    控制器,由用户将调用的REST端点组成。

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

    使用CORS的Spring启动应用程序

    @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;
        }
    }
    

    的应用程序属性文件
    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
    

    有两个测试用例

    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.

2 个答案:

答案 0 :(得分:1)

<强> 1)

我不知道您的测试究竟是什么样子,但也许系统认为您仍然登录?您可以尝试删除Cookie,以确保没有保存访问令牌。

另一个选项可能是Spring Boot无法识别Keycloak Adapter,因此无法保护访问。您主要通过添加keycloak-spring-boot-adapterkeycloak-tomcat8-adapter依赖项(more details here)来配置适配器。

2)

看起来CORS配置不正确。您可以考虑配置(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() {
        }
    });
}

答案 1 :(得分:0)

您还没有在pom.xml中添加Spring Boot Keycloak Adapter依赖项。

对于2.您还没有为/ check配置CORS(仅适用于/ api)

 <dependency>
      <groupId>org.keycloak</groupId>
      <artifactId>keycloak-spring-boot-adapter</artifactId>
      <version>${keycloak.version}</version>
  </dependency>
相关问题