Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Boot Admin with OAuth2 sample implementation #1262

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions spring-boot-admin-samples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<module>spring-boot-admin-sample-war</module>
<module>spring-boot-admin-sample-hazelcast</module>
<module>spring-boot-admin-sample-custom-ui</module>
<module>spring-boot-admin-sample-oauth2</module>
</modules>
<dependencyManagement>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
version: '3'

services:
authorization-server:
build:
context: ./spring-boot-admin-sample-oauth2-authorization
environment:
REDIRECT_URI: http://localhost:8080,http://localhost:8080/login/oauth2/code/admin
container_name: sba-oauth2-auth
ports:
- 8081:8081

admin-server:
build:
context: ./spring-boot-admin-sample-oauth2-admin
container_name: sba-oauth2-admin
environment:
cloudfoundry.uaa.host: authorization-server
cloudfoundry.uaa.port: 8081
spring.security.oauth2.client.provider.cloudfoundry-uaa.authorization-uri: >-
http://localhost:8081/uaa/oauth/authorize
security.logout.redirect-url: >-
http://localhost:8081/uaa/logout.do?client_id=admin&redirect=http://localhost:8080/login
depends_on:
- authorization-server
command: ["./wait-for-command.sh -t 120 -c 'curl authorization-server:8081/uaa' && java -jar app.jar"]
ports:
- 8080:8080

resource-server:
build:
context: ./spring-boot-admin-sample-oauth2-resource
container_name: sba-oauth2-resource
environment:
cloudfoundry.uaa.host: authorization-server
cloudfoundry.uaa.port: 8081
spring.boot.admin.client.url: http://admin-server:8080
depends_on:
- authorization-server
- admin-server
command: ["./wait-for-command.sh -t 120 -c 'curl admin-server:8080' && java -jar app.jar"]
ports:
- 8082:8082
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2014-2019 the original author or authors.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-boot-admin-sample-oauth2</artifactId>
<packaging>pom</packaging>
<name>Spring Boot Admin Sample OAuth2</name>
<description>Spring Boot Admin Sample OAuth2</description>
<parent>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-samples</artifactId>
<version>${revision}</version>
<relativePath>..</relativePath>
</parent>
<modules>
<module>spring-boot-admin-sample-oauth2-admin</module>
<module>spring-boot-admin-sample-oauth2-authorization</module>
<module>spring-boot-admin-sample-oauth2-resource</module>
</modules>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM openjdk:8-jre-alpine

RUN apk --no-cache add curl

COPY /target/spring-boot-admin-sample-oauth2-admin.jar app.jar

RUN wget -O wait-for-command.sh "https://raw.githubusercontent.com/ettore26/wait-for-command/master/wait-for-command.sh"
RUN chmod +x wait-for-command.sh

ENTRYPOINT ["/bin/sh", "-c"]

EXPOSE 8080
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2014-2019 the original author or authors.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-boot-admin-sample-oauth2-admin</artifactId>
<name>Spring Boot Admin Sample OAuth2 - Spring Boot Admin</name>
<description>Spring Boot Admin Sample OAuth2 - Spring Boot Admin</description>
<parent>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-sample-oauth2</artifactId>
<version>${revision}</version>
<relativePath>..</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8-standalone</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>
de.codecentric.boot.admin.sample.oauth2.SpringBootAdminOAuth2AdminServerApplication
</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package de.codecentric.boot.admin.sample.oauth2;

import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableAdminServer
@SpringBootApplication
public class SpringBootAdminOAuth2AdminServerApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBootAdminOAuth2AdminServerApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package de.codecentric.boot.admin.sample.oauth2.config;

import com.nimbusds.jose.util.Base64;
import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.web.client.HttpHeadersProvider;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.NonNull;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class AuthenticationHeaderProvider implements HttpHeadersProvider {

private static final String AUTHORIZATION_HEADER = "Authorization";

private final OAuth2AuthorizedClientServiceImpl clientService;
private final Environment environment;

public AuthenticationHeaderProvider(OAuth2AuthorizedClientServiceImpl clientService, Environment environment) {
this.clientService = clientService;
this.environment = environment;
}

@NonNull
@Override
public HttpHeaders getHeaders(@NonNull Instance instance) {
HttpHeaders headers = new HttpHeaders();

Optional<OAuth2AuthorizedClient> clientOptional = clientService.loadAuthorizedClientByScope("openid");

if (clientOptional.isPresent()) {
OAuth2AccessToken accessToken = clientOptional.get().getAccessToken();
headers.set(AUTHORIZATION_HEADER,
String.join(" ", accessToken.getTokenType().getValue(), accessToken.getTokenValue()));
} else {
String username = environment.getRequiredProperty("security.client.healthcheck.username");
String password = environment.getRequiredProperty("security.client.healthcheck.password");
headers.set(AUTHORIZATION_HEADER, "Basic " + Base64.encode(username + ":" + password));
}

return headers;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package de.codecentric.boot.admin.sample.oauth2.config;

import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.services.EndpointDetector;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class OAuth2AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

private final InstanceRepository instanceRepository;
private final EndpointDetector endpointDetector;

public OAuth2AuthenticationSuccessHandler(InstanceRepository instanceRepository,
EndpointDetector endpointDetector) {
this.instanceRepository = instanceRepository;
this.endpointDetector = endpointDetector;
}

@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
super.onAuthenticationSuccess(request, response, authentication);
detectEndpoints();
}

private void detectEndpoints() {
instanceRepository.findAll()
.map(Instance::getId)
.flatMap(endpointDetector::detectEndpoints)
.subscribe();
}

}