Skip to content

Commit

Permalink
Securing the system
Browse files Browse the repository at this point in the history
- Add authorization server.
- Making Gateway and Store services to be the Resource Servers.
- Add HTTPS support.
- Change test cases to work with security.
- Update docker-compose*.yml to add auth-server.
- Secure Eureka service.
  • Loading branch information
mohamed-taman committed May 8, 2020
1 parent a83dfd7 commit eb372c5
Show file tree
Hide file tree
Showing 46 changed files with 1,176 additions and 125 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,6 @@ build/

### VS Code ###
.vscode/

### Special files
test-em-all-external-auth.sh
36 changes: 24 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

- This project is a development of a small set of **Spring Boot** and **Cloud** based Microservices projects, that implement cloud-native intuitive, Reactive Programming, Event-driven, Microservices design patterns and coding best practices.
- The project follows [**CloudNative**](https://www.cncf.io/) recommendations and The [**twelve-factor app**](https://12factor.net/) methodology for building *software-as-a-service apps* to show how μServices should be built and deployed.
- This project is using cutting edge technologies like Docker, Kubernetes, Elasticsearch Stack for logging and monitoring, Java SE 14, MySQL, and MongoDB databases, all components developed with TDD in mind, covering integration & performance testing, and many more.
- This project uses cutting edge technologies like Docker, Kubernetes, Elasticsearch Stack for
logging and monitoring, Java SE 14, MySQL, and MongoDB databases, all components developed with TDD in mind, covering integration & performance testing, and many more.

------
I am developing this project as stages, and all such stages are documented under project
Expand All @@ -28,8 +29,9 @@ Springy Store μService --> Parent folder.
|- store-cloud-chassis --> Cloud services Parent POM, inherit from build contains all cloud libraries
|- store-service-chassis --> Parent POM, inherits from cloud contains all microservices common libraries
|-store-cloud-infra
|- authorization-server --> Authorization server
|- edge-server --> API Gateway server
|- eureka-server --> Service discovery server
|- edge-server --> API Gateway server
|-store-common
|- store-api --> API Endpoint and services definitions for all microservices
|- store-utils --> Common utilities shared between all components
Expand Down Expand Up @@ -67,9 +69,9 @@ The following topics are going to be covered in this 1st stage (other stages top
- Adding automated tests of microservices in isolation.
- Adding semi-automated tests to a microservice landscape.

### System Boundary - μServices Landscape (Release 4.8-Latest)
### System Boundary - μServices Landscape (Release 5.0-Latest)

![System Boundary](docs/stage1/app_ms_landscape.png)
![System Boundary](docs/diagram/app_ms_landscape.png)

### Required software

Expand Down Expand Up @@ -159,7 +161,7 @@ All build commands and test suite for each microservice should run successfully,

```bash
---------------< com.siriusxi.ms.store:store-aggregator >---------------
[INFO] Building Springy Store Aggregator 1.0-SNAPSHOT [12/12]
[INFO] Building Springy Store Aggregator 1.0-SNAPSHOT [13/13]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ store-aggregator ---
Expand All @@ -177,12 +179,13 @@ All build commands and test suite for each microservice should run successfully,
[INFO] Store Service ...................................... SUCCESS [ 8.927 s]
[INFO] Eureka Discovery Server ............................ SUCCESS [ 6.536 s]
[INFO] Edge Server ........................................ SUCCESS [ 32.108 s]
[INFO] Authorization Server ............................... SUCCESS [ 1.616 s]
[INFO] Springy Store Aggregator ........................... SUCCESS [ 0.100 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 55.663 s
[INFO] Finished at: 2020-04-26T03:38:34+02:00
[INFO] Total time: 57.663 s
[INFO] Finished at: 2020-05-08T03:38:34+02:00
[INFO] ------------------------------------------------------------------------
```

Expand All @@ -201,6 +204,7 @@ All the **services**, **databases**, and **messaging service** will run in paral
Creating network "ssm_default" with the default driver
Creating ssm_eureka_1 ... done
Creating ssm_gateway_1 ... done
Creating ssm_auth-server_1 ... done
Creating ssm_mysql_1 ... done
Creating ssm_mongodb_1 ... done
Creating ssm_rabbitmq_1 ... done
Expand Down Expand Up @@ -279,12 +283,15 @@ mohamed.taman@DTLNV8 ~/springy-store-microservices
The result will look like this:
```bash
Starting [Springy Store] full functionality testing....
Starting 'Springy Store μServices' for [Blackbox] testing....
Start: Sun, Apr 30, 2020 2:34:19 PM
Start Tests: Fri, May 8, 2020 12:26:28 PM
HOST=localhost
PORT=8080
Wait for: curl http://localhost:8080/actuator/health ... Ok
PORT=8443
Restarting the test environment...
$ docker-compose -p ssm down --remove-orphans
$ docker-compose -p ssm up -d
Wait for: curl -k https://localhost:8443/actuator/health... , retry #1 , retry #2, {"status":"UP"} DONE, continues...
Test OK (HTTP Code: 200)
Test OK (HTTP Code: 200)
Test OK (HTTP Code: 200)
Expand All @@ -305,7 +312,10 @@ Test OK (HTTP Code: 422, {"httpStatus":"UNPROCESSABLE_ENTITY","message":"Invalid
Test OK (actual value: "Invalid productId: -1")
Test OK (HTTP Code: 400, {"timestamp":"2020-04-12T12:34:26.471+00:00","path":"/store/api/v1/products/invalidProductId","status":400,"error":"Bad Request","message":"Type mismatch.","requestId":"044dcdf2-13"})
Test OK (actual value: "Type mismatch.")
End: Sun, Apr 30, 2020 2:34:26 PM
Test OK (HTTP Code: 401, )
Test OK (HTTP Code: 200)
Test OK (HTTP Code: 403, )
End, all tests OK: Fri, May 8, 2020 12:29:21 PM
```
### Closing The Story
Expand All @@ -326,6 +336,7 @@ Stopping ssm_product_1 ... done
Stopping ssm_review_1 ... done
Stopping ssm_mongodb_1 ... done
Stopping ssm_store_1 ... done
Stopping ssm_auth-server_1 ... done
Stopping ssm_mysql_1 ... done
Stopping ssm_rabbitmq_1 ... done
Stopping ssm_eureka_1 ... done
Expand All @@ -335,6 +346,7 @@ Removing ssm_product_1 ... done
Removing ssm_review_1 ... done
Removing ssm_mongodb_1 ... done
Removing ssm_store_1 ... done
Removing ssm_auth-server_1 ... done
Removing ssm_mysql_1 ... done
Removing ssm_rabbitmq_1 ... done
Removing ssm_eureka_1 ... done
Expand Down
Binary file added config/keystore/edge.p12
Binary file not shown.
16 changes: 15 additions & 1 deletion docker-compose-kafka.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,21 @@ services:
gateway:
build: store-cloud-infra/edge-server
ports:
- "8080:8080"
- "8443:8443"
environment:
- SPRING_PROFILES_ACTIVE=docker
- SERVER_SSL_KEY_STORE=file:/keystore/edge.p12
- SERVER_SSL_KEY_STORE_PASSWORD=password
volumes:
- $PWD/config/keystore:/keystore
depends_on:
- eureka
restart: on-failure
## End - Edge Server definition

## Start - Edge Server definition
auth-server:
build: store-cloud-infra/authorization-server
environment:
- SPRING_PROFILES_ACTIVE=docker
depends_on:
Expand Down
16 changes: 15 additions & 1 deletion docker-compose-partitions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,21 @@ services:
gateway:
build: store-cloud-infra/edge-server
ports:
- "8080:8080"
- "8443:8443"
environment:
- SPRING_PROFILES_ACTIVE=docker
- SERVER_SSL_KEY_STORE=file:/keystore/edge.p12
- SERVER_SSL_KEY_STORE_PASSWORD=password
volumes:
- $PWD/config/keystore:/keystore
depends_on:
- eureka
restart: on-failure
## End - Edge Server definition

## Start - Edge Server definition
auth-server:
build: store-cloud-infra/authorization-server
environment:
- SPRING_PROFILES_ACTIVE=docker
depends_on:
Expand Down
19 changes: 18 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ services:
store:
build: store-services/store-service
environment:
# - SPRING_PROFILES_ACTIVE=external-OAuth-Provider
- SPRING_PROFILES_ACTIVE=docker
depends_on:
- rabbitmq
Expand All @@ -54,7 +55,23 @@ services:
gateway:
build: store-cloud-infra/edge-server
ports:
- "8080:8080"
- "8443:8443"
environment:
# - SPRING_PROFILES_ACTIVE=external-OAuth-Provider
- SPRING_PROFILES_ACTIVE=docker
# dynamically change certificate at run time
- SERVER_SSL_KEY_STORE=file:/keystore/edge.p12
- SERVER_SSL_KEY_STORE_PASSWORD=password
volumes:
- $PWD/config/keystore:/keystore
depends_on:
- eureka
restart: on-failure
## End - Edge Server definition

## Start - Edge Server definition
auth-server:
build: store-cloud-infra/authorization-server
environment:
- SPRING_PROFILES_ACTIVE=docker
depends_on:
Expand Down
Binary file added docs/diagram/app_ms_landscape.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/stage1/app_ms_landscape.png
Binary file not shown.
36 changes: 33 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,40 @@
<artifactId>store-aggregator</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Springy Store Aggregator</name>
<description>Aggregator pom project for Springy μServices</description>
<description>Aggregator pom project for all Springy Store μServices</description>
<packaging>pom</packaging>

<!-- Start - Springy Store Project Owner -->
<developers>
<developer>
<id>0001</id>
<name>Mohamed Taman</name>
<email>[email protected]</email>
<roles>
<role>
Sr. Enterprise Architect
</role>
<role>
Lead Software Architect
</role>
</roles>
</developer>
</developers>
<!-- End - Springy Store Project Owner -->
<!-- Start - Springy Store source repository -->
<scm>
<connection>https://github.com/mohamed-taman/Springy-Store-Microservices.git</connection>
<developerConnection>[email protected]:mohamed-taman/Springy-Store-Microservices.git</developerConnection>
<tag>HEAD</tag>
</scm>
<!-- End - Springy Store source repository -->
<!-- Start - Springy Store issue management -->
<issueManagement>
<system>GitHub</system>
<url>https://github.com/mohamed-taman/Springy-Store-Microservices/issues</url>
</issueManagement>
<!-- End - Springy Store issue management -->

<properties>
<maven.install.skip>true</maven.install.skip>
<maven.deploy.skip>true</maven.deploy.skip>
Expand All @@ -28,7 +59,6 @@
<module>store-services/store-service</module>
<module>store-cloud-infra/eureka-server</module>
<module>store-cloud-infra/edge-server</module>


<module>store-cloud-infra/authorization-server</module>
</modules>
</project>
60 changes: 60 additions & 0 deletions store-cloud-infra/authorization-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#### Start of builder image
# ------------------------
# Builder stage to prepare application for final image
FROM openjdk:14-slim-buster as builder
WORKDIR temp

# Fatjar location, but could be set to different location from command line
ARG JAR_FILE=target/*.jar

# Copy fat jar file to current image builder
COPY ${JAR_FILE} application.jar

# Extract the jar file layers
RUN java -Djarmode=layertools -jar --enable-preview application.jar extract

# Workaround to avoid Copy command failure when directory is not exists.
RUN test ! -d ./snapshot-dependencies \
&& mkdir snapshot-dependencies \
&& echo "Directory [snapshot-dependencies] created."

#### End of builder stage

#### Start of actual image
# ------------------------
# Build image based on JDK 14 base image, based on latest debian buster OS
FROM openjdk:14-slim-buster
VOLUME /tmp

# Set image information, but could be set to different location from command line
ARG IMAGE_VERSION="1.0-SNAPSHOT"
ARG IMAGE_NAME="Authorization Server"
ARG MAINTAINER="Mohamed Taman <[email protected]>"

LABEL version=${IMAGE_VERSION} name=${IMAGE_NAME} maintainer=${MAINTAINER}

# Limiting security access to not user root user
RUN addgroup siriusxi && useradd -g siriusxi -ms /bin/bash taman

# Setting user to current created user
USER taman

# Set working directory to application folder
WORKDIR /home/taman/application

# Copy all layers from builder stage to current image
COPY --from=builder temp/dependencies/ ./
COPY --from=builder temp/snapshot-dependencies/ ./
COPY --from=builder temp/spring-boot-loader/ ./
COPY --from=builder temp/application/ ./

# Expose current server to port 9999
EXPOSE 9999

ARG JAVA_OPTS=""

# Run the application with JVM configs if any
ENTRYPOINT ["bash", "-c", \
"java -server --enable-preview -XX:+UseContainerSupport -XX:+ShowCodeDetailsInExceptionMessages \
-XX:+AlwaysActAsServerClassMachine -XX:+UseG1GC -XX:+UseStringDeduplication ${JAVA_OPTS} \
org.springframework.boot.loader.JarLauncher ${0} ${@}"]
54 changes: 54 additions & 0 deletions store-cloud-infra/authorization-server/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.siriusxi.ms.store</groupId>
<artifactId>store-cloud-chassis</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../store-base/store-cloud-chassis/pom.xml</relativePath>
</parent>

<groupId>com.siriusxi.cloud.infra</groupId>
<artifactId>auth-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Authorization Server</name>
<description>OAuth2 Authorization Server, based on Spring boot.</description>
<packaging>jar</packaging>

<properties>
<spring.security.jwt.jose.version>5.0.0.M5</spring.security.jwt.jose.version>
</properties>

<dependencies>
<!-- Start - To register API Gateway server with Eureka Discovery Server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- End - To register API Gateway server with Eureka Discovery Server -->

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt-jose</artifactId>
<version>${spring.security.jwt.jose.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.siriusxi.cloud.infra.auth.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;

@EnableAuthorizationServer
@SpringBootApplication
public class AuthorizationServer {

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

}
Loading

0 comments on commit eb372c5

Please sign in to comment.