rogerxu / rogerxu.github.io

Roger Xu's Blog
2 stars 2 forks source link

Cloud Foundry #202

Open rogerxu opened 6 years ago

rogerxu commented 6 years ago

Cloud Foundry Docs

rogerxu commented 6 years ago

Developer Guide

Developer Guide | Cloud Foundry Docs

rogerxu commented 6 years ago

Buildpacks

Buildpacks | Cloud Foundry Docs

Java

Java Buildpack | Cloud Foundry Docs

Node.js

Node.js Buildpack | Cloud Foundry Docs

Cloud Foundry automatically uses the Node.js buildpack if it detects a package.json file in the root directory of your project.

Staticfile

Staticfile Buildpack | Cloud Foundry Docs

Cloud Foundry requires a file named Staticfile in the root directory of the app to use the Staticfile buildpack with the app.

rogerxu commented 6 years ago

Security

Federated Identity for distributed Identity Management

Authentication - SAML 2.0

The Security Assertion Markup Language (SAML 2.0) is an open standard based on XML for exchanging authentication and authorization data of a principal (user) between an identity provider (IdP) and a service provider (SP). The data exchange is done through messages termed "Bearer Assertions". A "Bearer" is any party in possesion of the assertion. The integrity of the assertion is protected through XML encryption and XML signature. SAML addresses the requirement of web browser single sign-on across the internet.

Authorizations are expressed through "User-Groups" to which the principal is assigned to. It is up to the service provider and the respective implementation how the User-Groups are interpreted resp. translated into specific authorizations.

Authorization - OAuth 2.0

The OAuth 2.0 Authorization Framework is exclusively a protocol for delegating authorizations and not for authentication.

The OAuth 2.0 specification defines four roles:

JSON Web Tokens (JWT)

JWT is an emerging open standard that defines a compact token format for securely transmitting information between parties as a JSON object.

The cloud application has a trust relationship with the authorization server. The trust is configured in the environment variable VCAP_SERVICES for the approuter and each micro service. VCAP_SERVICES contains a credentials string for the UAA, which is created by the respective service broker when the approuter is bound to the UAA service instance. The credentials string contains, amongst other information - the public key corresponding to the private key of the UAA. The public key is used to verify the token signature.

Authentication - OpenID Connect

OpenID Connect is an authentication layer on top of the OAuth 2.0 Authorization Framework. It specifies a RESTful HTTP API, using JSON as a data format. The standard is also sometimes nicknamed as "Social Login", because it is supported by all recognized social networks (Facebook, Google, etc.) for authentication and single sign-on.

The XSA UAA relies on SAML 2.0 Assertions for the authentication process. Therefore, it is not possible to configure Google or Facebook as the identity provider for XSA UAA.

Authentication in XS UAA

In this flow it is important to notice that the JWT Token never appears in the browser. This is achieved by the "Authorization Code": with it, the user "authorizes" the approuter to obtain the authorizations - the JWT Token - from the XSA UAA component. The browser never needs to know about the authorizations, because the approuter enriches each subsequent request with the JWT Token, before the request is routed to the micro service.

  1. The user is authenticated by the SAML 2 IdP.
  2. The IdP issues a SAML 2 Bearer Assertion and sends it via browser redirection to the UAA component. The SAML 2 Bearer Assertion contains information about the users identity (user id, e-mail, etc.), his attributes (e.g. first and last name) and assigned user groups.
  3. The UAA memorizes this information in its own persistence and generates an authorization code and a JWT Token, based on the mappings of user groups to role collections and role collections to roles. The roles contain "scopes" of operation (functional authorizations) and "attributes" with respective values, describing the data on which a user is authorized to operate on (data authorizations).
  4. The UAA sends the Authorization Code via browser redirection to the Approuter.
  5. The Approuter then sends the Authorization Code to the UAA to obtain the JWT Token.
  6. The UAA performs a lookup with the Authorization Code presented by Approuter, finds the associated JWT Token and embeds it in the response. The JWT Token contains information about the users identity and his authorizations.
  7. The Approuter has obtained the authorizations of the user and operates now on his behalf: every user request to the business application goes through the Approuter, where it enriches the user request with the user´s authorizations (JWT Token), before the request is routed to the targeted service endpoint of the business application. The developer of the business application must ensure that every request contains a valid JWT Token, so that it is ensured that nobody has called the application directly (only via the Approuter) and that the request was sent by an authenticated user.

Each instance of Application Router holds it´s own mappings of JWT-Tokens to jSessionIDs. The mappings are not shared across multiple instances of Application Router nor are the mappings persisted in a common persistency. Application Router uses Cloud Foundry session stickiness (VCAP_ID) to ensure that requests belonging to the same session are routed via the same Application Router instance - this means that the user will need to re-authenticate if an Application Router instance of a particular session goes down and is recovered by a new Application Router instance

App2App Integration Scenario

XSA vs Cloud Foundry Security

Business Users vs. Cloud Foundry Users

Authorization Model

The authorization model of CF has a predefined role and scope set. Associations of CF user accounts to Org/Space roles are persisted in the Cloud Controller database of the CF installation.

The authorization model of a business app is defined in xs-security.json.

The role-templates are then used to derive roles with the Role Application Builder. The roles of a business app are persisted in the UAA Component of XSA.

rogerxu commented 6 years ago

Logging

Home · SAP/cf-java-logging-support Wiki

Writing Application Logs

Writing Application Logs · SAP/cf-java-logging-support Wiki

Maven Dependencies

pom.xml

<!-- Logging -->
<dependency>
    <groupId>com.sap.hcp.cf.logging</groupId>
    <artifactId>cf-java-logging-support-logback</artifactId>
    <version>${cf-logging-version}</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>

Logging Configuration

src/main/resources/logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <logger name="org.springframework.web" level="DEBUG"/>

    <!-- write logs to console -->
    <appender name="STDOUT-JSON" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encode and enrich full message with the required fields/tags -->
        <encoder class="com.sap.hcp.cf.logback.encoder.JsonEncoder"/>
    </appender>

    <!-- for local development, you may want to switch to a more human-readable layout -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%date %-5level [%thread] - [%logger] [%mdc] - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- default log level for all loggers is INFO by default -->
    <root level="${LOG_ROOT_LEVEL:-INFO}">
        <appender-ref ref="STDOUT-JSON" />
    </root>

    <!-- request metrics are reported using INFO level, so make sure the instrumentation loggers are set to that level -->
    <logger name="com.sap.hcp.cf" level="${LOG_HCP_CF_LEVEL:-INFO}" />
</configuration>

Logging Exceptions

private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

LOGGER.error("some accompanying message {}", "parameter", ex);

Logging Categories

Marker dbCall = MarkerFactory.getMarker("db-call");
String logMsg = createMsg(request);

LOGGER.info(dbCall, logMsg);

Custom Fields

import static com.sap.hcp.cf.logging.common.customfields.CustomField.customField;

LOGGER.info("Logging with custom field {}", customField("customKey", customValue));

Dynamic Log Levels

Dynamic Log Levels · SAP/cf-java-logging-support Wiki

Environment Variables

Logback Specific Configuration

In the logback.xml file, a turbofilter has to be defined by adding the following line to the configuration element:

<turboFilter class="com.sap.hcp.cf.logback.filter.CustomLoggingTurboFilter" />

Usage

A valid JWT token should be signed with RS256. Its payload should contain the email of the issuer, the desired log-level, a timestamp for the time at which the token has been generated and a timestamp that represents the expiry date. The Java class TokenCreator can be used to create valid tokens.

Header

{
  "alg": "RS256",
  "typ": "JWT"
}

Payload

{
  "issuer": "<valid e-mail address>",
  "level": "TRACE",
  "iat": 1506016127,
  "exp": 1506188927
}

Application Logging Service

cloud-cf-product-list-sample/README.md at master · SAP/cloud-cf-product-list-sample

Step 12 with SAP S/4HANA Cloud SDK: Logging with SAP S/4HANA Cloud SDK | SAP Blogs

rogerxu commented 6 years ago

Service to Service

Resilience - Hystrix

Each HystrixCommand is executed within a separate thread and is timed out automatically after 1000ms by default.

Synchronous execution

String string = new MyCommand().execute();

Asynchronous execution

Future<String> future = new MyCommand().queue();
String string = future.get();