Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用KeyClope实现一个基于令牌访问的简单web服务?_Java_Spring_Spring Boot_Keycloak - Fatal编程技术网

Java 如何使用KeyClope实现一个基于令牌访问的简单web服务?

Java 如何使用KeyClope实现一个基于令牌访问的简单web服务?,java,spring,spring-boot,keycloak,Java,Spring,Spring Boot,Keycloak,我想创建一个web服务,它将以以下方式工作: 客户端包含keydepeat并提供用户名和密码 KeyClope将访问令牌返回给客户端 使用该访问令牌,客户机访问由KeyClope保护的页面 我怎么做 我尝试的 步骤1:客户端获得访问令牌 private String getAccessToken() throws IOException { final CloseableHttpClient client = HttpClients.createDefault(); final

我想创建一个web服务,它将以以下方式工作:

  • 客户端包含keydepeat并提供用户名和密码

  • KeyClope将访问令牌返回给客户端

  • 使用该访问令牌,客户机访问由KeyClope保护的页面

  • 我怎么做

    我尝试的

    步骤1:客户端获得访问令牌

    private String getAccessToken() throws IOException {
        final CloseableHttpClient client = HttpClients.createDefault();
    
        final List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
        nameValuePairs.add(new BasicNameValuePair("client_id", "test-app"));
        nameValuePairs.add(new BasicNameValuePair("username", "user1"));
        nameValuePairs.add(new BasicNameValuePair("password", "user1"));
        nameValuePairs.add(new BasicNameValuePair("grant_type", "password"));
    
    
        try {
            final HttpPost post = new HttpPost("http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token");
            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            post.setHeader("Accept", "application/json");
            post.setHeader("Content-type", "application/x-www-form-urlencoded");
    
            final CloseableHttpResponse response = client.execute(post);
    
            final int statusCode = response.getStatusLine().getStatusCode();
    
            System.out.println(String.format("Result: %d", statusCode));
    
            if (statusCode != 200) {
                System.out.println("Something went wrong");
                return null;
            }
    
            final String responseTxt = EntityUtils.toString(response.getEntity());
            final JSONObject json = new JSONObject(responseTxt);
    
            final String accessToken = json.getString("access_token");
            return accessToken;
        } finally {
            try {
                client.close();
            } catch (final IOException exception) {
                exception.printStackTrace();
            }
        }
    }
    
    当我这样做的时候,我会得到keydape的登录页面作为响应,而不是web服务的响应

    如何配置web服务?

    以下是实际的web服务:

    @RestController
    public class SampleRestController {
        @RequestMapping("/test")
        public String test() {
            return "Hello, world!";
        }
    }
    
    安全配置:

    @Configuration
    @EnableWebSecurity
    @ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
    public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
        @Autowired
        public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
    
            KeycloakAuthenticationProvider keycloakAuthenticationProvider
                    = keycloakAuthenticationProvider();
            keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(
                    new SimpleAuthorityMapper());
            auth.authenticationProvider(keycloakAuthenticationProvider);
        }
        @Bean
        public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
            return new KeycloakSpringBootConfigResolver();
        }
    
    
        @Bean
        @Override
        protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
            return new RegisterSessionAuthenticationStrategy(
                    new SessionRegistryImpl());
        }
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            super.configure(http);
            http.authorizeRequests()
                    .antMatchers("/test*")
                    .hasRole("user")
                    .anyRequest()
                    .permitAll();
        }
    }
    
    application.properties

    server.port = 8090
    
    spring.main.allow-bean-definition-overriding=true
    
    
    keycloak.realm = myrealm 
    keycloak.auth-server-url = http://127.0.0.1:8080/auth
    keycloak.ssl-required = external
    keycloak.resource = test-app
    keycloak.public-client=true
    keycloak.security-constraints[0].authRoles[0]=user
    keycloak.security-constraints[0].securityCollections[0].patterns[0]=/test/*
    
    当我发送一个头部带有访问令牌的请求时,为了得到“Hello,world!”响应,我需要做哪些更改

    更新1:我发现问题的一部分——客户端配置错误。它应该是
    仅承载

    但是现在我得到了响应
    仅承载应用程序不允许启动浏览器登录

    更新2:通过以下服务配置,它可以工作

    server.port = 8090
    spring.main.allow-bean-definition-overriding=true
    keycloak.realm = myrealm
    keycloak.resource = test-app
    keycloak.auth-server-url = http://127.0.0.1:8080/auth
    keycloak.bearer-only = true
    keycloak.ssl-required = external
    keycloak.principal-attribute = preferred_username
    

    您使用了不正确的流或目的地。如果您想使用登录名/密码,您可以选择其中的两个:

  • 现在。您尝试访问,您的服务器检查您的登录,如果您没有-重定向到KeyClope。登录后,keydepot使用访问代码(非令牌)将您重定向到您的页面(或登录页面-我不记得了)。在此之后,您的服务将此代码发送到KeyClope并执行其他操作

  • 将流更改为密码流。在这种情况下,您将向您的服务发送用户名/密码(而不是keydove),您的服务将此凭据发送到keydove,然后再执行其他操作

  • 更新:

    我更喜欢用户使用第一个东西,但如果您需要通过其他程序登录,则最好使用其他机制<代码>客户端凭据或角色范围较小的自定义用户

    更新2:


    如果您确实需要使用auth令牌,那么可以使用实现自定义和自定义您的
    OAuth2RestTemplate
    。但这并不太容易

    我需要使用首先获取访问令牌(或代码)的流,然后使用该代码连接到应用程序。另请参阅我的更新1。如果要为beare配置KeyClope,而不是服务器,则需要将用于登录的KC客户端设置为公共或机密,而不仅仅是beare。仅承载客户端不打算在身份验证流中使用。您用来进行身份验证的流是直接访问授权,它用于兼容性,但是对于全新的应用程序,授权代码流更可取。顺便说一句,我在您的代码中看到了另一个问题,对于构建您使用的
    String.format(“承载%s”,accessToken))
    ,我想应该是
    String.format(“承载%s,accessToken))
    ;-)
    server.port = 8090
    spring.main.allow-bean-definition-overriding=true
    keycloak.realm = myrealm
    keycloak.resource = test-app
    keycloak.auth-server-url = http://127.0.0.1:8080/auth
    keycloak.bearer-only = true
    keycloak.ssl-required = external
    keycloak.principal-attribute = preferred_username