kandi background
Explore Kits

spring-boot-admin | Admin UI for administration of spring boot | Application Framework library

 by   codecentric Java Version: 2.6.6 License: Apache-2.0

 by   codecentric Java Version: 2.6.6 License: Apache-2.0

Download this library from

kandi X-RAY | spring-boot-admin Summary

spring-boot-admin is a Java library typically used in Server, Application Framework, Spring Boot applications. spring-boot-admin has no bugs, it has no vulnerabilities, it has build file available, it has a Permissive License and it has high support. You can download it from GitHub, Maven.
[![codecov](https://codecov.io/gh/codecentric/spring-boot-admin/branch/master/graph/badge.svg?token=u5SWsZpj5S)](https://codecov.io/gh/codecentric/spring-boot-admin) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/de.codecentric/spring-boot-admin/badge.svg)](https://maven-badges.herokuapp.com/maven-central/de.codecentric/spring-boot-admin/) [![Gitter](https://badges.gitter.im/codecentric/spring-boot-admin.svg)](https://gitter.im/codecentric/spring-boot-admin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge). This community project provides an admin interface for [Spring Boot <sup>®</sup>](http://projects.spring.io/spring-boot/ "Official Spring-Boot website") applications. Monitoring Python applications is available using [Pyctuator](https://github.com/SolarEdgeTech/pyctuator).
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • spring-boot-admin has a highly active ecosystem.
  • It has 10813 star(s) with 2879 fork(s). There are 680 watchers for this library.
  • There were 9 major release(s) in the last 12 months.
  • There are 45 open issues and 1391 have been closed. On average issues are closed in 65 days. There are 25 open pull requests and 0 closed requests.
  • It has a positive sentiment in the developer community.
  • The latest version of spring-boot-admin is 2.6.6
spring-boot-admin Support
Best in #Application Framework
Average in #Application Framework
spring-boot-admin Support
Best in #Application Framework
Average in #Application Framework

quality kandi Quality

  • spring-boot-admin has 0 bugs and 0 code smells.
spring-boot-admin Quality
Best in #Application Framework
Average in #Application Framework
spring-boot-admin Quality
Best in #Application Framework
Average in #Application Framework

securitySecurity

  • spring-boot-admin has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • spring-boot-admin code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
spring-boot-admin Security
Best in #Application Framework
Average in #Application Framework
spring-boot-admin Security
Best in #Application Framework
Average in #Application Framework

license License

  • spring-boot-admin is licensed under the Apache-2.0 License. This license is Permissive.
  • Permissive licenses have the least restrictions, and you can use them in most projects.
spring-boot-admin License
Best in #Application Framework
Average in #Application Framework
spring-boot-admin License
Best in #Application Framework
Average in #Application Framework

buildReuse

  • spring-boot-admin releases are available to install and integrate.
  • Deployable package is available in Maven.
  • Build file is available. You can build the component from source.
  • Installation instructions, examples and code snippets are available.
  • spring-boot-admin saves you 9703 person hours of effort in developing the same functionality from scratch.
  • It has 20614 lines of code, 1609 functions and 546 files.
  • It has medium code complexity. Code complexity directly impacts maintainability of the code.
spring-boot-admin Reuse
Best in #Application Framework
Average in #Application Framework
spring-boot-admin Reuse
Best in #Application Framework
Average in #Application Framework
Top functions reviewed by kandi - BETA

kandi has reviewed spring-boot-admin and discovered the below as its top functions. This is intended to give you an instant insight into spring-boot-admin implemented functionality, and help decide if they suit your requirements.

  • Deserialize a registration .
    • Create the request body for a given instance .
      • Appends events to the event log .
        • Converts an instance event to a Map .
          • Rewrite endpoint url .
            • The hazelcast configuration .
              • Forward to endpoint web .
                • Parses the build - version .
                  • Returns the HTTP headers for the given instance .
                    • Registers this application .

                      Get all kandi verified functions for this library.

                      Get all kandi verified functions for this library.

                      spring-boot-admin Key Features

                      Show health status

                      Show details, like

                      JVM &amp; memory metrics

                      micrometer.io metrics

                      Datasource metrics

                      Cache metrics

                      Show build-info number

                      Follow and download logfile

                      View jvm system- &amp; environment-properties

                      View Spring Boot Configuration Properties

                      Support for Spring Cloud’s postable /env- &amp;/refresh-endpoint

                      Easy loglevel management

                      Interact with JMX-beans

                      View thread dump

                      View http-traces

                      View auditevents

                      View http-endpoints

                      View scheduled tasks

                      View and delete active sessions (using spring-session)

                      View Flyway / Liquibase database migrations

                      Download heapdump

                      Notification on status change (via e-mail, Slack, Hipchat, …​)

                      Event journal of status changes (non persistent)

                      spring-boot-admin Examples and Code Snippets

                      See all related Code Snippets

                      Snapshot builds

                      copy iconCopydownload iconDownload
                      &lt;repository&gt;
                      	&lt;id&gt;sonatype-nexus-snapshots&lt;/id&gt;
                      	&lt;name&gt;Sonatype Nexus Snapshots&lt;/name&gt;
                      	&lt;url&gt;https://oss.sonatype.org/content/repositories/snapshots/&lt;/url&gt;
                      	&lt;snapshots&gt;
                      		&lt;enabled&gt;true&lt;/enabled&gt;
                      	&lt;/snapshots&gt;
                      	&lt;releases&gt;
                      		&lt;enabled&gt;false&lt;/enabled&gt;
                      	&lt;/releases&gt;
                      &lt;/repository&gt;

                      Build

                      copy iconCopydownload iconDownload
                      ./mvnw clean package

                      Making request to Spring Boot Admin server from custom view?

                      copy iconCopydownload iconDownload
                      data() {
                        return {
                          axios: require("axios") // usually this is imported at the top
                        }
                      }
                      
                      Vue.prototype.axios = require("axios")
                      
                      <script>
                      import axios from 'axios';
                      
                      export default {
                        created() {
                          axios.get()
                        }
                      }
                      </script>
                      
                      data() {
                        return {
                          axios: require("axios") // usually this is imported at the top
                        }
                      }
                      
                      Vue.prototype.axios = require("axios")
                      
                      <script>
                      import axios from 'axios';
                      
                      export default {
                        created() {
                          axios.get()
                        }
                      }
                      </script>
                      
                      data() {
                        return {
                          axios: require("axios") // usually this is imported at the top
                        }
                      }
                      
                      Vue.prototype.axios = require("axios")
                      
                      <script>
                      import axios from 'axios';
                      
                      export default {
                        created() {
                          axios.get()
                        }
                      }
                      </script>
                      
                      /* global SBA */
                      import example from './example';
                      import exampleEndpoint from './example-endpoint';
                      
                      SBA.use({
                          install({viewRegistry, axios}) {
                              viewRegistry.addView({
                                  name: 'example',
                                  path: '/example',
                                  component: example,
                                  label: 'Example',
                                  order: 1000,
                                  // this is where we pass it down with the props
                                  // first part is the name, second is the value
                                  props: { "axios": axios },
                              });
                          }
                      });
                      
                      <template>
                          <div>
                              <h1>Example View</h1>
                              <p>
                                  <b>GET /example:</b> <span v-text="exampleResponse" />
                              </p>
                          </div>
                      </template>
                      
                      <script>
                      export default {
                          props: {
                              applications: { type: Array, required: true },
                              // this is where we retrieve the prop. the name of the field should
                              // correspond to the name given above
                              axios: { type: Object, required: true },
                          },
                          data: () => ({
                              exampleResponse: "No response",
                          }),
                          async created() {
                              // Now we can use our axios instance! And it will be correctly
                              // configured for talking to Springboot Admin
                              this.axios.get("example")
                                  .then(r => { this.exampleResponse = r.data.response; })
                                  .catch(() => { this.exampleResponse = "Request failed!" });
                          },
                      };
                      </script>
                      
                      /* global SBA */
                      import example from './example';
                      import exampleEndpoint from './example-endpoint';
                      
                      SBA.use({
                          install({viewRegistry, axios}) {
                              viewRegistry.addView({
                                  name: 'example',
                                  path: '/example',
                                  component: example,
                                  label: 'Example',
                                  order: 1000,
                                  // this is where we pass it down with the props
                                  // first part is the name, second is the value
                                  props: { "axios": axios },
                              });
                          }
                      });
                      
                      <template>
                          <div>
                              <h1>Example View</h1>
                              <p>
                                  <b>GET /example:</b> <span v-text="exampleResponse" />
                              </p>
                          </div>
                      </template>
                      
                      <script>
                      export default {
                          props: {
                              applications: { type: Array, required: true },
                              // this is where we retrieve the prop. the name of the field should
                              // correspond to the name given above
                              axios: { type: Object, required: true },
                          },
                          data: () => ({
                              exampleResponse: "No response",
                          }),
                          async created() {
                              // Now we can use our axios instance! And it will be correctly
                              // configured for talking to Springboot Admin
                              this.axios.get("example")
                                  .then(r => { this.exampleResponse = r.data.response; })
                                  .catch(() => { this.exampleResponse = "Request failed!" });
                          },
                      };
                      </script>
                      

                      Spring Boot Admin Server and Client in the same application

                      copy iconCopydownload iconDownload
                      public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                      
                          @Override
                          protected void configure(HttpSecurity http) throws Exception {
                             
                              http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                                      .authorizeRequests().antMatchers("/soapWS/**").permitAll().and()
                                      .authorizeRequests().antMatchers("/actuator/**").permitAll()
                                      .anyRequest().authenticated().and()
                                      .httpBasic().and()
                                      .csrf().disable();
                          }
                      

                      How to solve java.lang.UnsupportedClassVersionError error? Where can I found the right JRE version?

                      copy iconCopydownload iconDownload
                      jlink -p <directory app jar> --add-modules <name of your module> --output custom_runtime
                      
                      $ mvn dependency:build-classpath -DincludeScope=runtime -Dmdep.outputFile=cp.txt
                      $ jdeps -classpath "<contents of cp.txt>" --multi-release 17 --print-module-deps --ignore-missing-deps <app jar>
                      
                      jlink --add-modules mod1,mod2,mod3 --output custom_runtime
                      
                      /path/to/custom/runtime/java -jar <app jar>
                      
                      jlink -p <directory app jar> --add-modules <name of your module> --output custom_runtime
                      
                      $ mvn dependency:build-classpath -DincludeScope=runtime -Dmdep.outputFile=cp.txt
                      $ jdeps -classpath "<contents of cp.txt>" --multi-release 17 --print-module-deps --ignore-missing-deps <app jar>
                      
                      jlink --add-modules mod1,mod2,mod3 --output custom_runtime
                      
                      /path/to/custom/runtime/java -jar <app jar>
                      
                      jlink -p <directory app jar> --add-modules <name of your module> --output custom_runtime
                      
                      $ mvn dependency:build-classpath -DincludeScope=runtime -Dmdep.outputFile=cp.txt
                      $ jdeps -classpath "<contents of cp.txt>" --multi-release 17 --print-module-deps --ignore-missing-deps <app jar>
                      
                      jlink --add-modules mod1,mod2,mod3 --output custom_runtime
                      
                      /path/to/custom/runtime/java -jar <app jar>
                      
                      jlink -p <directory app jar> --add-modules <name of your module> --output custom_runtime
                      
                      $ mvn dependency:build-classpath -DincludeScope=runtime -Dmdep.outputFile=cp.txt
                      $ jdeps -classpath "<contents of cp.txt>" --multi-release 17 --print-module-deps --ignore-missing-deps <app jar>
                      
                      jlink --add-modules mod1,mod2,mod3 --output custom_runtime
                      
                      /path/to/custom/runtime/java -jar <app jar>
                      

                      java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 10000ms in 'map' (and no fallback has been configured)

                      copy iconCopydownload iconDownload
                      server:
                        port: 8002
                      
                      spring:
                        application:
                          name: user-service
                        datasource:
                          driver-class-name: com.mysql.cj.jdbc.Driver
                          url: jdbc:mysql://localhost:3306/test
                          username: root
                          password: root
                          
                        jpa:
                          generate-ddl: true
                          hibernate:
                            ddl-auto: create
                       
                      #  zipkin:
                      #    base-url: http://127.0.0.1:9411/
                      
                      eureka:
                        client:
                          register-with-eureka: true
                          fetch-registry: true
                        instance:
                          prefer-ip-address: true
                          hostname: localhost
                          
                      

                      Spring Cloud sleuth memory leak issue

                      copy iconCopydownload iconDownload
                      <parent>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-parent</artifactId>
                          <version>2.1.4.RELEASE</version>
                          <relativePath /> <!-- lookup parent from repository -->
                      </parent>
                      
                      <dependency>
                                  <groupId>org.springframework.cloud</groupId>
                                  <artifactId>spring-cloud-dependencies</artifactId>
                                  <version>Greenwich.SR4</version>
                                  <type>pom</type>
                                  <scope>import</scope>
                              </dependency>
                      

                      SpringBoot Admin custom authentication flow when accessing client

                      copy iconCopydownload iconDownload
                      
                        @Bean
                        public HttpHeadersProvider customHttpHeadersProvider(YourCustomProperties properties) {
                          return instance -> {
                            if (properties.getAppNames().contains(instance.getRegistration().getName())) {
                              // do jwt stuff here
                              return new HttpHeaders();
                            }else {
                              HttpHeaders httpHeaders = new HttpHeaders();
                              httpHeaders.add("X-CUSTOM", "My Custom Value");
                              return httpHeaders;
                            }
                          };
                        }
                      

                      GitHub Actions: Cache Maven .m2 repository on Windows environment C\:\\Users\runneradmin\\.m2\repository: Cannot stat: No such file or directory

                      copy iconCopydownload iconDownload
                      steps:
                        - uses: actions/checkout@v2
                        - name: Set up JDK 1.8
                          uses: actions/setup-java@v1
                          with:
                            java-version: 1.8
                        - name: Cache Maven packages
                          uses: actions/cache@v2.1.4
                          with:
                            path: ~/.m2
                            key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
                            restore-keys: ${{ runner.os }}-m2
                        - name: Build with Maven
                          run: mvn --batch-mode --update-snapshots verify
                      

                      Spring Boot 2.4.3 - Actuator /startup endpoint not found

                      copy iconCopydownload iconDownload
                      @SpringBootApplication
                      public class DemoApplication {
                      
                          public static void main(String[] args) {
                              SpringApplication app = new SpringApplication(DemoApplication.class);
                              app.setApplicationStartup(new BufferingApplicationStartup(1000));
                              app.run(args);
                          }
                      }
                      
                      management.endpoints.web.exposure.include=startup
                      
                      @SpringBootApplication
                      public class DemoApplication {
                      
                          public static void main(String[] args) {
                              SpringApplication app = new SpringApplication(DemoApplication.class);
                              app.setApplicationStartup(new BufferingApplicationStartup(1000));
                              app.run(args);
                          }
                      }
                      
                      management.endpoints.web.exposure.include=startup
                      

                      Spring boot admin: Client can't register with admin server over https

                      copy iconCopydownload iconDownload
                      public class SpringBootAdminClientAutoConfiguration {
                          ...
                          @Configuration(proxyBeanMethods = false)
                          @ConditionalOnBean(RestTemplateBuilder.class)
                          public static class BlockingRegistrationClientConfig {
                              @Bean
                              @ConditionalOnMissingBean
                              public BlockingRegistrationClient registrationClient(ClientProperties client) {
                                  RestTemplateBuilder builder = new RestTemplateBuilder().setConnectTimeout(client.getConnectTimeout())
                                          .setReadTimeout(client.getReadTimeout());
                                  if (client.getUsername() != null && client.getPassword() != null) {
                                      builder = builder.basicAuthentication(client.getUsername(), client.getPassword());
                                  }
                                  return new BlockingRegistrationClient(builder.build());
                              }
                          }   
                      
                      @Bean
                      public BlockingRegistrationClient registrationClient(
                              @Value("${ssl.protocol}") String protocol,
                              @Value("${ssl.trustStore.path}") String trustStorePath,
                              @Value("${ssl.trustStore.password}") String trustStorePassword,
                              ClientProperties client) throws Exception {
                      
                          SSLContext sslContext = SSLContextBuilder.create()
                                  .loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray())
                                  .setProtocol(protocol)
                                  .build();
                      
                          CloseableHttpClient httpClient = HttpClientBuilder.create()
                                  .setSSLContext(sslContext)
                                  .build();
                      
                          RestTemplateBuilder builder = new RestTemplateBuilder()
                                  .setConnectTimeout(client.getConnectTimeout())
                                  .setReadTimeout(client.getReadTimeout())
                                  .requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient));
                      
                          if (client.getUsername() != null && client.getPassword() != null) {
                              builder = builder.basicAuthentication(client.getUsername(), client.getPassword());
                          }
                          return new BlockingRegistrationClient(builder.build());
                      }
                      
                      ssl:
                        protocol: TLSv1.2
                        trustStore:
                          path: "/opt/java/openjdk/lib/security/cacerts"
                          password: "*****"
                      
                      public class SpringBootAdminClientAutoConfiguration {
                          ...
                          @Configuration(proxyBeanMethods = false)
                          @ConditionalOnBean(RestTemplateBuilder.class)
                          public static class BlockingRegistrationClientConfig {
                              @Bean
                              @ConditionalOnMissingBean
                              public BlockingRegistrationClient registrationClient(ClientProperties client) {
                                  RestTemplateBuilder builder = new RestTemplateBuilder().setConnectTimeout(client.getConnectTimeout())
                                          .setReadTimeout(client.getReadTimeout());
                                  if (client.getUsername() != null && client.getPassword() != null) {
                                      builder = builder.basicAuthentication(client.getUsername(), client.getPassword());
                                  }
                                  return new BlockingRegistrationClient(builder.build());
                              }
                          }   
                      
                      @Bean
                      public BlockingRegistrationClient registrationClient(
                              @Value("${ssl.protocol}") String protocol,
                              @Value("${ssl.trustStore.path}") String trustStorePath,
                              @Value("${ssl.trustStore.password}") String trustStorePassword,
                              ClientProperties client) throws Exception {
                      
                          SSLContext sslContext = SSLContextBuilder.create()
                                  .loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray())
                                  .setProtocol(protocol)
                                  .build();
                      
                          CloseableHttpClient httpClient = HttpClientBuilder.create()
                                  .setSSLContext(sslContext)
                                  .build();
                      
                          RestTemplateBuilder builder = new RestTemplateBuilder()
                                  .setConnectTimeout(client.getConnectTimeout())
                                  .setReadTimeout(client.getReadTimeout())
                                  .requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient));
                      
                          if (client.getUsername() != null && client.getPassword() != null) {
                              builder = builder.basicAuthentication(client.getUsername(), client.getPassword());
                          }
                          return new BlockingRegistrationClient(builder.build());
                      }
                      
                      ssl:
                        protocol: TLSv1.2
                        trustStore:
                          path: "/opt/java/openjdk/lib/security/cacerts"
                          password: "*****"
                      
                      public class SpringBootAdminClientAutoConfiguration {
                          ...
                          @Configuration(proxyBeanMethods = false)
                          @ConditionalOnBean(RestTemplateBuilder.class)
                          public static class BlockingRegistrationClientConfig {
                              @Bean
                              @ConditionalOnMissingBean
                              public BlockingRegistrationClient registrationClient(ClientProperties client) {
                                  RestTemplateBuilder builder = new RestTemplateBuilder().setConnectTimeout(client.getConnectTimeout())
                                          .setReadTimeout(client.getReadTimeout());
                                  if (client.getUsername() != null && client.getPassword() != null) {
                                      builder = builder.basicAuthentication(client.getUsername(), client.getPassword());
                                  }
                                  return new BlockingRegistrationClient(builder.build());
                              }
                          }   
                      
                      @Bean
                      public BlockingRegistrationClient registrationClient(
                              @Value("${ssl.protocol}") String protocol,
                              @Value("${ssl.trustStore.path}") String trustStorePath,
                              @Value("${ssl.trustStore.password}") String trustStorePassword,
                              ClientProperties client) throws Exception {
                      
                          SSLContext sslContext = SSLContextBuilder.create()
                                  .loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray())
                                  .setProtocol(protocol)
                                  .build();
                      
                          CloseableHttpClient httpClient = HttpClientBuilder.create()
                                  .setSSLContext(sslContext)
                                  .build();
                      
                          RestTemplateBuilder builder = new RestTemplateBuilder()
                                  .setConnectTimeout(client.getConnectTimeout())
                                  .setReadTimeout(client.getReadTimeout())
                                  .requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient));
                      
                          if (client.getUsername() != null && client.getPassword() != null) {
                              builder = builder.basicAuthentication(client.getUsername(), client.getPassword());
                          }
                          return new BlockingRegistrationClient(builder.build());
                      }
                      
                      ssl:
                        protocol: TLSv1.2
                        trustStore:
                          path: "/opt/java/openjdk/lib/security/cacerts"
                          password: "*****"
                      

                      Specify spring expression language filter for KubernetesDiscoveryClient in Spring Boot Admin

                      copy iconCopydownload iconDownload
                      Expression filterExpr = this.parser.parseExpression(spelExpression);
                      filteredServices = (Service instance) -> {
                          Boolean include = filterExpr.getValue(this.evalCtxt, instance, Boolean.class);
                          ...
                      };
                      
                      spring:
                          cloud:
                              kubernetes:
                                  discovery:
                                      namespace: myname
                                      all-namespaces: true
                                      filter: "#root.metadata.name matches '.*string.*'"
                                      service-labels:
                                          "[app.kubernetes.io/part-of]": myapp
                      
                      Expression filterExpr = this.parser.parseExpression(spelExpression);
                      filteredServices = (Service instance) -> {
                          Boolean include = filterExpr.getValue(this.evalCtxt, instance, Boolean.class);
                          ...
                      };
                      
                      spring:
                          cloud:
                              kubernetes:
                                  discovery:
                                      namespace: myname
                                      all-namespaces: true
                                      filter: "#root.metadata.name matches '.*string.*'"
                                      service-labels:
                                          "[app.kubernetes.io/part-of]": myapp
                      

                      See all related Code Snippets

                      Community Discussions

                      Trending Discussions on spring-boot-admin
                      • Why does a Keycloak bearer token appear to be truncated during security filter chain processing
                      • Making request to Spring Boot Admin server from custom view?
                      • Spring Boot Admin Server and Client in the same application
                      • When running spring-boot container on kubernetes active processor count is set with host CPU, not k8s cpu limit for container
                      • How to solve java.lang.UnsupportedClassVersionError error? Where can I found the right JRE version?
                      • Getting 404 when access spring admin
                      • java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 10000ms in 'map' (and no fallback has been configured)
                      • Spring Cloud sleuth memory leak issue
                      • SpringBoot Admin custom authentication flow when accessing client
                      • GitHub Actions: Cache Maven .m2 repository on Windows environment C\:\\Users\runneradmin\\.m2\repository: Cannot stat: No such file or directory
                      Trending Discussions on spring-boot-admin

                      QUESTION

                      Why does a Keycloak bearer token appear to be truncated during security filter chain processing

                      Asked 2022-Mar-24 at 08:15

                      I am working with Keycloak 16.1.0, spring boot 2.6.2 and an external application client that sends a bearer token in to my server application to the endpoint http://romanmed-host:8888/actuator/health.

                      By cranking the debugging level up to maximum, I can see the access token before its processed. I can verify that its accurate by using the JWT Debug site JSON Web Tokens to verify that the signature is correct.

                      Yet several lines later in the output log the same bearer token appears to be somewhat truncated, its listed with an error saying that it failed to verify. When checked by using the JWT site indicates a signature error, but the token content is correct.

                      Naturally I would like to know why it appears to be truncated and what I can do about it.

                      • I can match the output from the client program to the server and its not been changed, so truncation must occur within the server program.
                      • The program is accepting the request by a get request, since the token can be checked by JWT as valid at this point, its not truncated by the get request input method.
                      • I have not inserted a filter in the security filter chain, so I can see how any of my code could be doing anything to invalid the token.
                      • Other than the Failed to verify token no other error messages are generated, suggesting that until this point everything is correct.

                      I can see that the WebAsyncManagerIntegrationFilter, SecurityContextPersistenceFilter, HeaderWriterFilter,KeycloakPreAuthActionsFilter and KeycloakAuthenticationProcessingFilter have all been invoked.

                      I am assuming that the problem is somewhere within the KeycloakAuthenticationProcessingFilter, but I don't understand why the token appears to have been truncated at this point.

                      The received bearer token is

                      eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ3dUhKc1pvWnduelVsU1Zqc2JyTkxsbUNhR0ZIVkV0cTcyQkI5V0pORTVVIn0.eyJleHAiOjE2NDY0MDI3NTAsImlhdCI6MTY0NjQwMjQ1MCwianRpIjoiMjIyMjUxZDgtNDYxMy00OGQwLWEwNzAtMjU5YTYyY2NhZDkyIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDg1L2F1dGgvcmVhbG1zL0Jvb3RBZG1pbiIsImF1ZCI6WyJybS1jb25maWctc2VydmVyIiwiYXBwLXRvZG8iLCJhY2NvdW50Il0sInN1YiI6Ijc4ZTU1YjhiLWQ5MjAtNGQ0Yi1hNWQ5LWIyZDk3MDYzNDgyYiIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFwcC1hZG1pbiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDozMDAwMSJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtYm9vdGFkbWluIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsicm0tY29uZmlnLXNlcnZlciI6eyJyb2xlcyI6WyJhY3R1YXRvciJdfSwiYXBwLWFkbWluIjp7InJvbGVzIjpbImFjdHVhdG9yIl19LCJhcHAtdG9kbyI6eyJyb2xlcyI6WyJhY3R1YXRvciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiY2xpZW50SWQiOiJhcHAtYWRtaW4iLCJjbGllbnRIb3N0IjoiMTI3LjAuMC4xIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzZXJ2aWNlLWFjY291bnQtYXBwLWFkbWluIiwiY2xpZW50QWRkcmVzcyI6IjEyNy4wLjAuMSJ9.fwQPLiSIrUSjnRnTBrd1vvGic49OSf7aGDemc0TdmTshZzJ-eYhiEqnAh9-QU2rxDayPIhoIzA9CgBXmGPCnl1Qu4CujDddpBcLpnjszBoBdzwjDgpShgwFpGk0fGCM0fxtSZgMWRfeS_sRjBpRzZ42GelCYZ2E1kZX_E7o_LB3thpiv5oYqgTNucusNmzpm0-iFcEUe5rfnu2ZOHI_hLQvIYKlGURnNld4jov-KDLf2QTh2h3XqjbsGHG9PDq4MbFPhKY_9yF0jQkhF6F3oYrw9MIH4SbemrR-CHw6-aWqGmgucjJ7iKMY5o86HxLPu2tzM06NdaurQZX4ImLCBlQ

                      Its truncated format is

                      eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ3dUhKc1pvWnduelVsU1Zqc2JyTkxsbUNhR0ZIVkV0cTcyQkI5V0pORTVVIn0.eyJleHAiOjE2NDY0MDI3NTAsImlhdCI6MTY0NjQwMjQ1MCwianRpIjoiMjIyMjUxZDgtNDYxMy00OGQwLWEwNzAtMjU5YTYyY2NhZDkyIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDg1L2F1dGgvcmVhbG1zL0Jvb3RBZG1pbiIsImF1ZCI6WyJybS1jb25maWctc2VydmVyIiwiYXBwLXRvZG8iLCJhY2NvdW50Il0sInN1YiI6Ijc4ZTU1YjhiLWQ5MjAtNGQ0Yi1hNWQ5LWIyZDk3MDYzNDgyYiIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFwcC1hZG1pbiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDozMDAwMSJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtYm9vdGFkbWluIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsicm0tY29uZmlnLXNlcnZlciI6eyJyb2xlcyI6WyJhY3R1YXRvciJdfSwiYXBwLWFkbWluIjp7InJvbGVzIjpbImFjdHVhdG9yIl19LCJhcHAtdG9kbyI6eyJyb2xlcyI6WyJhY3R1YXRvciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiY2xpZW50SWQiOiJhcHAtYWRtaW4iLCJjbGllbnRIb3N0IjoiMTI3LjAuMC4xIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzZXJ2aWNlLWFjY291bnQtYXBwLWFkbWluIiwiY2xpZW50QWRkcmVzcyI6IjEyNy4wLjAuMSJ9

                      The debug log is

                      servletPath:/actuator/health
                      pathInfo:null
                      headers:
                      accept-encoding: gzip
                      user-agent: ReactorNetty/1.0.13
                      host: romanmed-host:8888
                      authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ3dUhKc1pvWnduelVsU1Zqc2JyTkxsbUNhR0ZIVkV0cTcyQkI5V0pORTVVIn0.eyJleHAiOjE2NDY0MDI3NTAsImlhdCI6MTY0NjQwMjQ1MCwianRpIjoiMjIyMjUxZDgtNDYxMy00OGQwLWEwNzAtMjU5YTYyY2NhZDkyIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDg1L2F1dGgvcmVhbG1zL0Jvb3RBZG1pbiIsImF1ZCI6WyJybS1jb25maWctc2VydmVyIiwiYXBwLXRvZG8iLCJhY2NvdW50Il0sInN1YiI6Ijc4ZTU1YjhiLWQ5MjAtNGQ0Yi1hNWQ5LWIyZDk3MDYzNDgyYiIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFwcC1hZG1pbiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDozMDAwMSJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtYm9vdGFkbWluIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsicm0tY29uZmlnLXNlcnZlciI6eyJyb2xlcyI6WyJhY3R1YXRvciJdfSwiYXBwLWFkbWluIjp7InJvbGVzIjpbImFjdHVhdG9yIl19LCJhcHAtdG9kbyI6eyJyb2xlcyI6WyJhY3R1YXRvciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiY2xpZW50SWQiOiJhcHAtYWRtaW4iLCJjbGllbnRIb3N0IjoiMTI3LjAuMC4xIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzZXJ2aWNlLWFjY291bnQtYXBwLWFkbWluIiwiY2xpZW50QWRkcmVzcyI6IjEyNy4wLjAuMSJ9.fwQPLiSIrUSjnRnTBrd1vvGic49OSf7aGDemc0TdmTshZzJ-eYhiEqnAh9-QU2rxDayPIhoIzA9CgBXmGPCnl1Qu4CujDddpBcLpnjszBoBdzwjDgpShgwFpGk0fGCM0fxtSZgMWRfeS_sRjBpRzZ42GelCYZ2E1kZX_E7o_LB3thpiv5oYqgTNucusNmzpm0-iFcEUe5rfnu2ZOHI_hLQvIYKlGURnNld4jov-KDLf2QTh2h3XqjbsGHG9PDq4MbFPhKY_9yF0jQkhF6F3oYrw9MIH4SbemrR-CHw6-aWqGmgucjJ7iKMY5o86HxLPu2tzM06NdaurQZX4ImLCBlQ
                      accept: application/vnd.spring-boot.actuator.v2+json, application/vnd.spring- 
                      boot.actuator.v1+json, application/json
                      
                      
                      Security filter chain: [
                         WebAsyncManagerIntegrationFilter
                         SecurityContextPersistenceFilter
                         HeaderWriterFilter
                         KeycloakPreAuthActionsFilter
                         KeycloakAuthenticationProcessingFilter
                         LogoutFilter
                         RequestCacheAwareFilter
                         SecurityContextHolderAwareRequestFilter
                         KeycloakSecurityContextRequestFilter
                         KeycloakAuthenticatedActionsFilter
                         AnonymousAuthenticationFilter
                         SessionManagementFilter
                         ExceptionTranslationFilter
                         FilterSecurityInterceptor
                      ]
                      
                      
                      ************************************************************
                      2022-03-04 14:03:30.088 TRACE 99667 --- [.1-8888-exec-10] o.s.security.web.FilterChainProxy        : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@2caa9666, org.springframework.security.web.context.SecurityContextPersistenceFilter@67683210, org.springframework.security.web.header.HeaderWriterFilter@58a9e64d, org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter@3fecb076, org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter@41d84abb, org.springframework.security.web.authentication.logout.LogoutFilter@3e563293, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@25511895, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@21202507, org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter@62159fd, org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter@28e8dee7, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@263f6e96, org.springframework.security.web.session.SessionManagementFilter@d3b0397, org.springframework.security.web.access.ExceptionTranslationFilter@75d0cac6, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@2267b0bb]] (1/1)
                      2022-03-04 14:03:30.088 DEBUG 99667 --- [.1-8888-exec-10] o.s.security.web.FilterChainProxy        : Securing GET /actuator/health
                      2022-03-04 14:03:30.089 TRACE 99667 --- [.1-8888-exec-10] o.s.security.web.FilterChainProxy        : Invoking WebAsyncManagerIntegrationFilter (1/14)
                      2022-03-04 14:03:30.089 TRACE 99667 --- [.1-8888-exec-10] o.s.security.web.FilterChainProxy        : Invoking SecurityContextPersistenceFilter (2/14)
                      2022-03-04 14:03:30.089 TRACE 99667 --- [.1-8888-exec-10] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
                      2022-03-04 14:03:30.089 TRACE 99667 --- [.1-8888-exec-10] w.c.HttpSessionSecurityContextRepository : Created SecurityContextImpl [Null authentication]
                      2022-03-04 14:03:30.089 DEBUG 99667 --- [.1-8888-exec-10] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
                      2022-03-04 14:03:30.089 TRACE 99667 --- [.1-8888-exec-10] o.s.security.web.FilterChainProxy        : Invoking HeaderWriterFilter (3/14)
                      2022-03-04 14:03:30.089 TRACE 99667 --- [.1-8888-exec-10] o.s.security.web.FilterChainProxy        : Invoking KeycloakPreAuthActionsFilter (4/14)
                      2022-03-04 14:03:30.089 DEBUG 99667 --- [.1-8888-exec-10] o.k.adapters.PreAuthActionsHandler       : adminRequest http://romanmed-host:8888/actuator/health
                      2022-03-04 14:03:30.089 TRACE 99667 --- [.1-8888-exec-10] o.s.security.web.FilterChainProxy        : Invoking KeycloakAuthenticationProcessingFilter (5/14)
                      2022-03-04 14:03:30.089 DEBUG 99667 --- [.1-8888-exec-10] f.KeycloakAuthenticationProcessingFilter : Attempting Keycloak authentication
                      2022-03-04 14:03:30.089 TRACE 99667 --- [.1-8888-exec-10] o.k.adapters.RequestAuthenticator        : --> authenticate()
                      2022-03-04 14:03:30.089 TRACE 99667 --- [.1-8888-exec-10] o.k.adapters.RequestAuthenticator        : try bearer
                      2022-03-04 14:03:30.089 DEBUG 99667 --- [.1-8888-exec-10] o.k.a.BearerTokenRequestAuthenticator    : Found [1] values in authorization header, selecting the first value for Bearer.
                      2022-03-04 14:03:30.089 DEBUG 99667 --- [.1-8888-exec-10] o.k.a.BearerTokenRequestAuthenticator    : Verifying access_token
                      2022-03-04 14:03:30.089 TRACE 99667 --- [.1-8888-exec-10] o.k.a.BearerTokenRequestAuthenticator    :    access_token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ3dUhKc1pvWnduelVsU1Zqc2JyTkxsbUNhR0ZIVkV0cTcyQkI5V0pORTVVIn0.eyJleHAiOjE2NDY0MDI3NTAsImlhdCI6MTY0NjQwMjQ1MCwianRpIjoiMjIyMjUxZDgtNDYxMy00OGQwLWEwNzAtMjU5YTYyY2NhZDkyIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDg1L2F1dGgvcmVhbG1zL0Jvb3RBZG1pbiIsImF1ZCI6WyJybS1jb25maWctc2VydmVyIiwiYXBwLXRvZG8iLCJhY2NvdW50Il0sInN1YiI6Ijc4ZTU1YjhiLWQ5MjAtNGQ0Yi1hNWQ5LWIyZDk3MDYzNDgyYiIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFwcC1hZG1pbiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDozMDAwMSJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtYm9vdGFkbWluIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsicm0tY29uZmlnLXNlcnZlciI6eyJyb2xlcyI6WyJhY3R1YXRvciJdfSwiYXBwLWFkbWluIjp7InJvbGVzIjpbImFjdHVhdG9yIl19LCJhcHAtdG9kbyI6eyJyb2xlcyI6WyJhY3R1YXRvciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiY2xpZW50SWQiOiJhcHAtYWRtaW4iLCJjbGllbnRIb3N0IjoiMTI3LjAuMC4xIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzZXJ2aWNlLWFjY291bnQtYXBwLWFkbWluIiwiY2xpZW50QWRkcmVzcyI6IjEyNy4wLjAuMSJ9.signature
                      2022-03-04 14:03:30.091 DEBUG 99667 --- [.1-8888-exec-10] o.k.a.BearerTokenRequestAuthenticator    : Failed to verify token
                      2022-03-04 14:03:30.091 DEBUG 99667 --- [.1-8888-exec-10] o.k.adapters.RequestAuthenticator        : Bearer FAILED
                      2022-03-04 14:03:30.091 DEBUG 99667 --- [.1-8888-exec-10] f.KeycloakAuthenticationProcessingFilter : Auth outcome: FAILED
                      2022-03-04 14:03:30.092 TRACE 99667 --- [.1-8888-exec-10] f.KeycloakAuthenticationProcessingFilter : Failed to process authentication request
                      
                      org.keycloak.adapters.springsecurity.KeycloakAuthenticationException: Invalid authorization header, see WWW-Authenticate header for detailsr code here
                      

                      The code is taken from an example by Thomas Darimont at Securing Spring Boot Admin & actuator endpoints with Keycloak and assumed to be correct.

                      The code is as follows

                      import lombok.extern.slf4j.Slf4j;
                      import org.keycloak.KeycloakPrincipal;
                      import org.keycloak.KeycloakSecurityContext;
                      import org.keycloak.adapters.springboot.KeycloakSpringBootProperties;
                      import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
                      import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
                      import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
                      import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
                      import org.springframework.beans.factory.annotation.Autowired;
                      import org.springframework.boot.actuate.health.HealthEndpoint;
                      import org.springframework.boot.actuate.info.InfoEndpoint;
                      import org.springframework.boot.context.properties.EnableConfigurationProperties;
                      import org.springframework.context.annotation.Bean;
                      import org.springframework.context.annotation.Scope;
                      import org.springframework.context.annotation.ScopedProxyMode;
                      import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
                      import org.springframework.security.config.annotation.web.builders.HttpSecurity;
                      import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
                      import org.springframework.security.core.session.SessionRegistry;
                      import org.springframework.security.core.session.SessionRegistryImpl;
                      import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
                      import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
                      import org.springframework.web.context.WebApplicationContext;
                      import org.springframework.web.context.request.RequestContextHolder;
                      import org.springframework.web.context.request.ServletRequestAttributes;
                      import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; 
                      import java.security.Principal;
                      
                      @KeycloakConfiguration
                      @Slf4j
                      @EnableConfigurationProperties(KeycloakSpringBootProperties.class)
                      
                      class KeycloakSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
                      
                      @Override
                      protected void configure(HttpSecurity http) throws Exception {
                      
                          super.configure(http);
                          http
                                  .csrf().disable()
                                  .authorizeRequests()
                                  .requestMatchers(EndpointRequest.to(
                                          InfoEndpoint.class,
                                          HealthEndpoint.class
                                  )).permitAll()
                                  .requestMatchers(EndpointRequest.toAnyEndpoint())
                                  .hasRole("ACTUATOR")
                                  .anyRequest().permitAll()
                          
                          ;
                      }
                      
                      
                      /**
                       * Use {@link KeycloakAuthenticationProvider}
                       *
                       * @param auth
                       * @throws Exception
                       */
                      @Autowired
                      public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
                      
                          SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
                          grantedAuthorityMapper.setPrefix("ROLE_");
                          grantedAuthorityMapper.setConvertToUpperCase(true);
                          KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
                          keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthorityMapper);
                          auth.authenticationProvider(keycloakAuthenticationProvider);
                      }
                      
                      @Bean
                      @Override
                      protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
                          return new RegisterSessionAuthenticationStrategy(buildSessionRegistry());
                      }
                      
                      @Bean
                      protected SessionRegistry buildSessionRegistry() {
                          return new SessionRegistryImpl();
                      }
                      
                      /**
                       * Allows to inject requests scoped wrapper for {@link KeycloakSecurityContext}.
                       *
                       * Returns the {@link KeycloakSecurityContext} from the Spring
                       * {@link ServletRequestAttributes}'s {@link Principal}.
                       * <p>
                       * The principal must support retrieval of the KeycloakSecurityContext, so at
                       * this point, only {@link KeycloakPrincipal} values and
                       * {@link KeycloakAuthenticationToken} are supported.
                       *
                       * @return the current <code>KeycloakSecurityContext</code>
                       */
                      @Bean
                      @Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
                      public KeycloakSecurityContext provideKeycloakSecurityContext() {
                          ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                          Principal principal = attributes.getRequest().getUserPrincipal();
                          if (principal == null) {
                              return null;
                          }
                      
                          if (principal instanceof KeycloakAuthenticationToken) {
                              principal = Principal.class.cast(KeycloakAuthenticationToken.class.cast(principal).getPrincipal());
                          }
                      
                          if (principal instanceof KeycloakPrincipal) {
                              return KeycloakPrincipal.class.cast(principal).getKeycloakSecurityContext();
                          }
                          return null;
                      }
                      

                      ANSWER

                      Answered 2022-Mar-07 at 08:32

                      The problem is the set up of the client and server programs.

                      The server used the value

                      auth-server-url: http://localhost:8085/auth

                      in its application.yml file to define the location of the Keycloak server, the client used the value

                      auth-server-url: http://romanmed-host:8085/auth

                      to define the location of Keycloak where the machine name romanmed-host is an alias for localhost. Having changed these values to be the same value, everything works as expected.

                      The diagnostics generated by the debugging/trace code are confusing, string described as truncated header seems to be truncated the bearer token, with out the signature. What the 'Keycloak` diagnostic is attempting to print is the part of the token which defines the tokens permissions and not the signature section.

                      Running the entire bearer token through the JWT site does show that the token is valid, because its a correctly encoded token and is legitimate.

                      The problem is not the token, but the way the token is being used! The client was expecting a legal signed token generated by them instance of Keycloak that it knew about, what it got was a legal signed token generated by Keycloak with a different address, which it correctly objected to.

                      The problem being the nature of the generated error message, it just claimed that the token signature was invalid, had it said something about an invalid/unexpected hostname, the nature of the problem would have been rather more obvious and resolved much faster. Keycloak is design to be flexible, so error messages tend to more vague to cover all situations, hence the message there is something wrong with your bearer token signature which is correct, but vague.

                      There seems to several schools of thought on how to resolve issues like this, one is to use an raw ip address which will always resolve to the same value. Thus avoid problems like this. This suffers from if the Keycloak server is moved to another machine there are lots of values to change.

                      My solution is to define an alias value in the hosts/dns server for the address of the eycloak server and always use that value in the support files. Hence if the Keycloak server is ever moved to another address, there is only one value to change.

                      Source https://stackoverflow.com/questions/71353307

                      Community Discussions, Code Snippets contain sources that include Stack Exchange Network

                      Vulnerabilities

                      No vulnerabilities reported

                      Install spring-boot-admin

                      [A quick guide](http://codecentric.github.io/spring-boot-admin/2.5.1/#getting-started) to get started can be found in our docs.
                      Please make sure you set $JAVA_HOME points to the correct JDK.
                      JDK >= 1.8

                      Support

                      Having trouble with codecentric’s Spring Boot Admin? We’d like to help!.

                      DOWNLOAD this Library from

                      Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
                      over 430 million Knowledge Items
                      Find more libraries
                      Reuse Solution Kits and Libraries Curated by Popular Use Cases
                      Explore Kits

                      Save this library and start creating your kit

                      Share this Page

                      share link
                      Reuse Pre-built Kits with spring-boot-admin
                      Consider Popular Application Framework Libraries
                      Try Top Libraries by codecentric
                      Compare Application Framework Libraries with Highest Support
                      Compare Application Framework Libraries with Highest Quality
                      Compare Application Framework Libraries with Highest Security
                      Compare Application Framework Libraries with Permissive License
                      Compare Application Framework Libraries with Highest Reuse
                      Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
                      over 430 million Knowledge Items
                      Find more libraries
                      Reuse Solution Kits and Libraries Curated by Popular Use Cases
                      Explore Kits

                      Save this library and start creating your kit

                      • © 2022 Open Weaver Inc.