keycloak(春季启动)未验证REST端点 [英] keycloak (spring boot) Not authenticating REST endpoint

查看:124
本文介绍了keycloak(春季启动)未验证REST端点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用诸如keycloak之类的开源用户管理服务.构建一个angularJs应用程序,该应用程序会将HTTP请求发送到由keycloak保护的REST端点.我在后端使用Spring Boot.我能够呼叫端点并获得不可能的结果,因为它会阻止来自未授权来源的请求.

这是我关注的两个链接

  1. 带有角靴和弹簧靴的钥匙斗

2.

带有CORS的Spring Boot应用程序

@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,这是正确的行为.但是,当我打电话给check/test时,我得到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.

解决方案

1)

我不知道您的测试看起来如何,但是也许系统认为您仍在登录?您可以尝试删除Cookie,以确保没有保存访问令牌.

另一个选择可能是Spring Boot无法识别Keycloak适配器,因此不能保护访问.您主要通过添加keycloak-spring-boot-adapterkeycloak-tomcat8-adapter依赖项(此处有更多详细信息).

2)

似乎CORS配置不正确.您可以考虑将这种实现用于配置(更多详细信息在这里):

@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() {
        }
    });
}

I am trying to play around with open source user management service like keycloak. Building a angularJs app that will be send HTTP request to REST endpoint secured by keycloak. I am using spring boot on the backend. I am able to call the endpoint and get result which should not be possible since it should block request coming from unauthorized source.

These are the two links that I followed

  1. keycloak with angular and spring boot

2.Github link to keycloak example

Controller which consists of REST endpoint that the user will call.

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

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

Spring boot application with CORS

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

Application properties files for

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

There are two test case

  1. Making REST call without logging in. In this case I am able to get the result back. This should not be the case, I get should blocked(get 401 error).

  2. Making REST call when logged in. I am able to call the api/getSample and this is the correct behavior. However when I call check/test I get 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.

解决方案

1)

I don't know how exactly your test looks like, but maybe the system thinks that you are still logged in? You could try to delete your cookies to make sure that there's no access token saved.

Another Option could be that Spring Boot doesn't recognize the Keycloak Adapter and therefore doesn't secure the access. You mainly configure the Adapter by adding the keycloak-spring-boot-adapterand keycloak-tomcat8-adapterdependencies (more details here).

2)

It looks like the CORS is not configured properly. You could consider this implementation for the configuration (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() {
        }
    });
}

这篇关于keycloak(春季启动)未验证REST端点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆