My latest and most complete articles are in the pumpkin slow say www.pkslow.com, welcome to tea!

1 introduction

There is not much introduction to Spring Cloud Data Flow here. If you are interested, you can read the following articles. This article focuses on integrating Data Flow and CloudFoundry UAA for permission control, rather than giving anyone direct access.

Spring Cloud Data Flow

Initial experience of Spring Cloud Data Flow, running in Local mode

Deploy Spring Cloud Data Flow on Kubernetes and run another task

Spring Cloud Data Flow is operated by Shell to facilitate CICD establishment

The source code has finally solved the problem of DataFlow deploying K8s applications

UAA, CloudFoundry User Account and Authentication, an Authentication and authorization service system, mainly used by CloudFoundry, can also serve as a stand-alone OAuth2 server to issue tokens to clients. It can be used in scenarios such as single sign-on SSO.

UAA can also integrate LDAP, but for the sake of simplicity, this article shows only the simplest integration.

2 Start the UAA service

War is available as a war package, which can be downloaded and deployed on Servlet containers such as Tomcat. UAA Bundled Bundled war packages with Springboot, making launching applications as easy as applying Springboot. This article is launched in this form.

Maven-dependency -plugin to download the war package:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <id>copy</id>
      <phase>process-resources</phase>
      <goals>
        <goal>copy</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <artifactItems>
      <! -- Local IDE startup required -->
      <artifactItem>
        <groupId>org.cloudfoundry.identity</groupId>
        <artifactId>cloudfoundry-identity-uaa</artifactId>
        <version>4.30.0</version>
        <type>war</type>
        <overWrite>true</overWrite>
        <outputDirectory>${project.basedir}/src/main/resources</outputDirectory>
        <destFileName>uaa.war</destFileName>
      </artifactItem>
      <! -- Packaging into jars requires -->
      <artifactItem>
        <groupId>org.cloudfoundry.identity</groupId>
        <artifactId>cloudfoundry-identity-uaa</artifactId>
        <version>4.30.0</version>
        <type>war</type>
        <overWrite>true</overWrite>
        <outputDirectory>${project.basedir}/target/classes</outputDirectory>
        <destFileName>uaa.war</destFileName>
      </artifactItem>
    </artifactItems>
  </configuration>
</plugin>
Copy the code

Called from a Springboot main function entry:

@SpringBootApplication
public class UaaServer {

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

    @Bean
    public ServletWebServerFactory servletContainer(a) throws IOException {

        final File tempDirectory = Files.createTempDirectory("uaa").toFile();
        final File tempUaaYmlFile = new File(tempDirectory, "uaa.yml");
        final File tempUaaWarFile = new File(tempDirectory, "uaa.war");

        FileCopyUtils.copy(
                new ClassPathResource("uaa.yml").getInputStream(),
                new FileOutputStream(tempUaaYmlFile));

        FileCopyUtils.copy(
                new ClassPathResource("uaa.war").getInputStream(),
                new FileOutputStream(tempUaaWarFile));

        System.out.println("uaa.yml: " + tempUaaYmlFile.getAbsolutePath());
        System.out.println("uaa.war: " + tempUaaWarFile.getAbsolutePath());

        System.setProperty("UAA_CONFIG_FILE", tempUaaYmlFile.getAbsolutePath());

        return new TomcatServletWebServerFactory() {
            protected TomcatWebServer getTomcatWebServer(org.apache.catalina.startup.Tomcat tomcat) {
                final Server tomcatServer = tomcat.getServer();
                final File catalinaBase = new File(tempDirectory, "catalina");
                catalinaBase.mkdirs();

                tomcatServer.setCatalinaBase(catalinaBase);
                new File(tomcatServer.getCatalinaBase(), "webapps").mkdirs();
                try {
                    Context context = tomcat.addWebapp("/uaa", tempUaaWarFile.toString());
                    final ClassLoader properClassLoader = UaaServer.class.getClassLoader();

                    WebappLoader loader =
                            new WebappLoader(properClassLoader);
                    context.setLoader(loader);

                } catch (Exception ex) {
                    throw new IllegalStateException("Failed to add webapp", ex);
                }
                return super.getTomcatWebServer(tomcat); }}; }}Copy the code

The filename of the configuration file and the WAR package are hardcoded, and the actual project can be implemented through configuration.

Then you need to configure uaa.yml file, see the code github.com/LarryDpk/pk… I won’t post it here. Note that JWT keys need to be generated:

$ openssl genrsa -out signingkey.pem 2048 Generating RSA private key, 2048 bit long modulus ........................ + + +... +++ e is 65537 (0x10001) $ openssl rsa -in signingkey.pem -pubout -out verificationkey.pem
writing RSA key
Copy the code

After completing the above steps, you are ready to pack and start, using the following command:

MVN Clean Package Java-jar target/ Cloudfoundry - UAA-server-1.0-snapshot.jarCopy the code

The default port number is 8080. Starts successfully, you can visit: http://localhost:8080/uaa/login

3 Configuring an Account

For convenience, we use an in-memory database to hold the account information, which will be lost upon reboot. Use the uAAC command line tool provided by UAA to create users and permissions. Since UAAC is Ruby based, you need to install Ruby first, which is already on my computer, so I won’t demonstrate it here.

To install the command line tool cf-UaAC faster, change the source of Ruby package management tool gem:

$ gem sources --add https://gems.ruby-china.com
https://gems.ruby-china.com added to sources

$ gem sources -l
*** CURRENT SOURCES ***
https://rubygems.org/
https://gems.ruby-china.com

$ gem sources --remove https://rubygems.org/
https://rubygems.org/ removed from sources
Copy the code

After configuring the domestic source, install:

$ sudo gem install cf-uaac
15 gems installed
Copy the code

Once the installation is complete, you can create users by using the following command.

uaac target http://localhost:8080/uaa uaac token client get admin -s adminsecret uaac client add dataflow \ --name dataflow \ --secret dataflow \ --scope cloud_controller.read,cloud_controller.write,openid,password.write,scim.userids,sample.create,sample.view,dataflow.creat e,dataflow.deploy,dataflow.destroy,dataflow.manage,dataflow.modify,dataflow.schedule,dataflow.view \ --authorized_grant_types password,authorization_code,client_credentials,refresh_token \ --authorities uaa.resource,dataflow.create,dataflow.deploy,dataflow.destroy,dataflow.manage,dataflow.modify,dataflow.schedule,dataflow .view,sample.view,sample.create \ --redirect_uri http://localhost:9393/login \ --autoapprove openid uaac group add"sample.view"
uaac group add "sample.create"
uaac group add "dataflow.view"
uaac group add "dataflow.create"
uaac group add "dataflow.deploy"
uaac group add "dataflow.destroy"
uaac group add "dataflow.manage"
uaac group add "dataflow.modify"
uaac group add "dataflow.schedule"


uaac user add larry -p larry --emails [email protected]
uaac member add "dataflow.view" larry
uaac member add "dataflow.create" larry
uaac member add "dataflow.deploy" larry
uaac member add "dataflow.destroy" larry
uaac member add "dataflow.manage" larry
uaac member add "dataflow.modify" larry
uaac member add "dataflow.schedule" larry

uaac user add vieweronly -p mysecret --emails [email protected]
uaac member add "dataflow.view" vieweronly
Copy the code

The key here are users and groups, namely users and groups. Only the information configured here corresponds to the Data Flow Server configuration.

4 Configure and start the Data Flow Server

The Data Flow Server configuration file is very important as it is the key to integrating UAA. The key is two parts. The first part is to configure various UAA information, such as clientId, Token address, and various authentication addresses. The second part is role mapping. Data Flow is role-based permission control. Only when its role is mapped to UAA group can it be used normally.

The configuration is as follows:

spring:
  security:
    oauth2:
      client:
        registration:
          uaa:
            client-id: dataflow
            client-secret: dataflow
            redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
            authorization-grant-type: authorization_code
            scope:
              - openid
              - dataflow.create
              - dataflow.deploy
              - dataflow.destroy
              - dataflow.manage
              - dataflow.modify
              - dataflow.schedule
              - dataflow.view
        provider:
          uaa:
            jwk-set-uri: http://localhost:8080/uaa/token_keys
            token-uri: http://localhost:8080/uaa/oauth/token
            user-info-uri: http://localhost:8080/uaa/userinfo
            user-name-attribute: user_name
            authorization-uri: http://localhost:8080/uaa/oauth/authorize
      resourceserver:
        opaquetoken:
          introspection-uri: http://localhost:8080/uaa/introspect
          client-id: dataflow
          client-secret: dataflow
  cloud:
    dataflow:
      security:
        authorization:
          provider-role-mappings:
            uaa:
              map-oauth-scopes: true
              role-mappings:
                ROLE_VIEW: dataflow.view
                ROLE_CREATE: dataflow.create
                ROLE_MANAGE: dataflow.manage
                ROLE_DEPLOY: dataflow.create
                ROLE_DESTROY: dataflow.create
                ROLE_MODIFY: dataflow.create
                ROLE_SCHEDULE: dataflow.create
Copy the code

As you can see, multiple different roles can map to the same group, which is very flexible.

After configuration, start Data Flow Server:

java -jar data-flow-server.jar --spring.config.additional-location=./src/main/resources/application.yaml
Copy the code

It’s time to experience the results

After successfully starting UAA and configuring users, and then starting Data Flow Server, you can start using it. The process is as follows:

Visit http://localhost:9393/dashboard/#/apps will automatically jump to the login page, click the uaa:

Jump to the LOGIN page of UAA:

Enter the configured account password: larry/larry, it shows Email, but it is not. Confirm authorization after login:

After authorization, it will automatically jump back to the Data Flow interface and have permission to view operations:

After you log out, ask to log in again. So far, we have successfully integrated.

The use of shell is as follows:

$java-jar spring-cloud-dataflow-shell-2.7.0.jar \ --dataflow.uri=http://localhost:9393 \ --dataflow.username=my_username \ --dataflow.password=my_password \ --skip-ssl-validationtrue    
Copy the code

conclusion

This article demonstrates how to integrate Data Flow Server and UAA step by step to achieve Data Flow security requirements. The actual UAA should use another database, such as MySQL, or consolidate LDAP, so that restart account data is not lost. We’ll talk about it later.

Please check the code: github.com/LarryDpk/pk…


Reference Documents:

Data Flow official document version 2.7.0

A Quick Guide To Using Cloud Foundry UAA