Add Security Sample Guide and Code.
Resolves gh-81.
This commit is contained in:
committed by
John Blum
parent
39535538fa
commit
a918c9a8f1
@@ -21,6 +21,11 @@ applications with Spring Boot.
|
||||
| Explains what auto-configuration is provided by SBDG out-of-the-box and what the auto-configuration is doing.
|
||||
| {github-samples-url}/boot/configuration[Boot Auto-Configuration]
|
||||
|
||||
| link:guides/boot-security.html[Security with Spring Boot for Apache Geode/Pivotal GemFire]
|
||||
| Explains how to configure auth and SSL/TLS for Apache Geode and Pivotal Cloud Cache powered
|
||||
applications with Spring Boot.
|
||||
| {github-samples-url}/boot/security[Boot Security]
|
||||
|
||||
| link:guides/boot-actuator.html[Spring Boot Actuator for Apache Geode/Pivotal GemFire]
|
||||
| Explains how to use Spring Boot Actuator for Apache Geode and how it works.
|
||||
| {github-samples-url}/boot/actuator[Boot Actuator]
|
||||
|
||||
237
spring-geode-docs/src/docs/asciidoc/guides/boot-security.adoc
Normal file
237
spring-geode-docs/src/docs/asciidoc/guides/boot-security.adoc
Normal file
@@ -0,0 +1,237 @@
|
||||
[[geode-samples-boot-security]]
|
||||
= Spring Boot Security for Apache Geode & Pivotal GemFire
|
||||
Patrick Johnson
|
||||
:pcc-docs: https://docs.pivotal.io/p-cloud-cache/1-11
|
||||
:shiro-docs: https://shiro.apache.org/realm
|
||||
:gemfire-name: VMware Tanzu GemFire
|
||||
:geode-name: Apache Geode
|
||||
:toc: left
|
||||
:toclevels: 2
|
||||
:stylesdir: ../
|
||||
:highlightjsdir: ../js/highlight
|
||||
:docinfodir: guides
|
||||
|
||||
This guide walks you through building a simple Spring Boot application with security, specifically auth and SSL. You
|
||||
should already be familiar with Spring Boot and Apache Geode/Tanzu GemFire.
|
||||
|
||||
[#index-link]
|
||||
link:../index.html[Index]
|
||||
|
||||
link:../index.html#geode-samples[Back to Samples]
|
||||
|
||||
[[geode-samples-boot-security-background]]
|
||||
== Background
|
||||
|
||||
Security is critical to most applications.
|
||||
It is important to be able to control who can access your application and what they are allowed to do, this is where
|
||||
auth (authentication and authorization) comes in. Authentication is used to verify a client’s identity (human or
|
||||
application) in exchange for some sort of credentials. Once authenticated, a client must be authorized before they can
|
||||
perform any actions. Authorization checks the permissions required to perform an action (read data, edit data, change
|
||||
configuration, etc.) against the permissions assigned to the client’s identity. Of course, sending passwords and other
|
||||
data as plain text isn’t very secure, so we also need to enable SSL/TLS to encrypt those things. Now, our apps are
|
||||
secure.
|
||||
|
||||
TIP: See the Spring Boot for {geode-name} (SBDG) chapter on link:../index.html#geode-security[Security] for more information.
|
||||
|
||||
[[geode-samples-boot-security-client]]
|
||||
== Securing a Client Application
|
||||
|
||||
Enabling auth on the client is mostly taken care of by Spring Boot’s Auto-configuration. In the `application.properties`
|
||||
file, simply set the properties `spring.data.gemfire.security.username` and `spring.data.gemfire.security.password` to
|
||||
the username and password your app will use to authenticate.
|
||||
Enabling SSL on the client requires you to put your `trusted.keystore` file (a Java KeyStore) in a well-known place, such
|
||||
as your application’s working directory or your home directory, and auto-configuration will do the rest. If your
|
||||
`trusted.keystore` has a password (which it should), you will need to specify it using the
|
||||
`spring.data.gemfire.security.ssl.keystore.password` property in your `application.properties` file. You can generate a
|
||||
Keystore using Java Keytool.
|
||||
|
||||
|
||||
TIP: See the Spring Boot for {geode-name} (SBDG) chapter on link:../index.html#geode-security-auth-clients[Auth for Clients]
|
||||
for more information.
|
||||
|
||||
[[geode-samples-boot-security-server]]
|
||||
== Securing a Server Application
|
||||
|
||||
Auto-configuration doesn’t do as much for you when configuring auth on the server as it does on the client. In order to
|
||||
enable auth, you need to do two things. First, annotate your configuration class with `@EnableSecurity`. Second, because
|
||||
Apache Geode’s security is integrated with Apache Shiro, define at least one Shiro Realm as a bean in your Spring
|
||||
`ApplicationContext`.
|
||||
|
||||
Below is an example Shiro Realm bean:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::{samples-dir}/boot/security/src/main/java/example/app/security/server/BootGeodeSecurityServerApplication.java[tags=realm]
|
||||
----
|
||||
|
||||
You can find more information on Apache Shiro and how to set up a Realm link:{shiro-docs}[here].
|
||||
|
||||
Enabling SSL on the server is essentially the same as for the client, just put your `trusted.keystore` file (a Java
|
||||
KeyStore) in a well-known place, like your application’s working directory or your home directory. If your
|
||||
`trusted.keystore` has a password (which it should), you will need to specify it using the
|
||||
`spring.data.gemfire.security.ssl.keystore.password` property in your `application.properties` file. You can generate a
|
||||
Keystore using Java Keytool.
|
||||
|
||||
|
||||
TIP: See the Spring Boot for {geode-name} (SBDG) chapter on link:../index.html#geode-security-auth-servers[Auth for Servers]
|
||||
for more information.
|
||||
|
||||
[[geode-samples-boot-security-examle]]
|
||||
== Example
|
||||
|
||||
To demonstrate the proper way to configure a Spring Boot application with security, we have put together a simple
|
||||
example. The example is made up of two main parts:
|
||||
|
||||
A client - BootGeodeSecurityClientApplication.
|
||||
|
||||
A server - BootGeodeSecurityServerApplication.
|
||||
|
||||
=== What it Does
|
||||
|
||||
The example is very minimal and only performs some basic data operations. The server starts up, and the client then
|
||||
connects to the server and tries to do two things:
|
||||
|
||||
1. Write a new value into Customers, which succeeds.
|
||||
2. Read a value from Customers, which fails because the user that the client authenticates with, is only authorized to
|
||||
write data, not read it.
|
||||
|
||||
This behavior may change, depending on the credentials used to authenticate. For example, using “cluster_operator”
|
||||
credentials on the platform will result in both read and write operations succeeding.
|
||||
|
||||
|
||||
=== Classes
|
||||
|
||||
[[geode-samples-boot-security-example-classes-client]]
|
||||
==== BootGeodeSecurityClientApplication
|
||||
|
||||
This class is an Apache Geode client application that is configured to authenticate when connecting to a server and to
|
||||
communicate using SSL.
|
||||
|
||||
[[geode-samples-boot-security-example-classes-server]]
|
||||
==== BootGeodeSecurityServerApplication
|
||||
|
||||
This class is an Apache Geode server application that requires authentication for clients to connect to it and is
|
||||
configured to communicate using SSL.
|
||||
|
||||
[[geode-samples-boot-security-example-classes-customer]]
|
||||
==== Customer
|
||||
|
||||
This is a simple domain class to represent a customer. The `Customers` region will contain `Customer` objects that will
|
||||
be accessed from the client.
|
||||
|
||||
[[geode-samples-boot-security-example-classes-controller]]
|
||||
==== SecurityController
|
||||
|
||||
This class is a RestController that exposes an endpoint at “/message” that verifies the clients use of SSL.
|
||||
|
||||
[[geode-samples-boot-security-example-run]]
|
||||
=== Running the Example
|
||||
|
||||
[[geode-samples-boot-security-example-run-local]]
|
||||
==== Running Locally
|
||||
|
||||
To run the example, first start the BootGeodeSecurityServerApplication and then run BootGeodeSecurityClientApplication.
|
||||
In the terminal you should see the following output:
|
||||
|
||||
[source]
|
||||
----
|
||||
Successfully wrote data to region Customers
|
||||
Attempting to read data from region Customers
|
||||
Read failed because "jdoe not authorized for DATA:READ:Customers:2"
|
||||
----
|
||||
|
||||
You can also hit the endpoint at https://localhost:8080/message[localhost:8080/message] to verify that the application
|
||||
is using SSL.
|
||||
|
||||
[[geode-samples-boot-security-example-run-platform]]
|
||||
==== Running on VMware Tanzu GemFire
|
||||
|
||||
In order for this sample to work, your Tanzu GemFire[VMs] tile must be set up to work with TLS. Instructions to enable
|
||||
TLS for the TanzuGemfire[VMs] can be found link: {pcc-docs}/prepare-TLS.html[here].
|
||||
|
||||
Once TLS has been enabled, create your service instance with the `-c '{"tls":true}' flag`.
|
||||
|
||||
For example:
|
||||
|
||||
[source]
|
||||
----
|
||||
cf create-service p-cloudcache [plan-name] [service-instance-name] -c '{"tls":true}'
|
||||
----
|
||||
|
||||
where `[plan-name]` is replaced with the plan you are selecting and `[service-instance-name]` is replaced with the
|
||||
desired name of your service.
|
||||
|
||||
Update your `manifest.yml` file with the `[service-instance-name]`
|
||||
[source]
|
||||
----
|
||||
services:
|
||||
- [your-service-instance-name]
|
||||
----
|
||||
|
||||
Before deploying the application to the platform, you must update the username and password in the
|
||||
`application.properties` file with the correct credentials for your service instance.
|
||||
|
||||
Once your Service Instance is created you’ll need to create a service-key for the service.
|
||||
[source]
|
||||
----
|
||||
cf create-service-key [service-instance-name] [service-key-name]
|
||||
----
|
||||
|
||||
where `[service-instance-name]` is replaced with the name of your service instance (from above) and `[service-key-name]`
|
||||
is what you would like to call this service key.
|
||||
|
||||
Once the service key is created, access the credentials in the service with the following command
|
||||
[source]
|
||||
----
|
||||
cf service-key [service-instance-name] [service-key-name]
|
||||
----
|
||||
|
||||
where `[service-instance-name]` is replaced with the name of your service instance and `[service-key-name]` is replaced
|
||||
with the name of your service key (from the previous step).
|
||||
|
||||
In the output look for the “users” section. For this example, we used the “cluster_operator” user credentials.
|
||||
[source]
|
||||
----
|
||||
{
|
||||
...
|
||||
"users": [
|
||||
{
|
||||
"password": "xxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"roles": [
|
||||
"cluster_operator"
|
||||
],
|
||||
"username": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"password": "xxxxxxxxxxxxxxxxxxxxxx",
|
||||
"roles": [
|
||||
"developer"
|
||||
],
|
||||
"username": "xxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"password": "xxxxxxxxxxxxxxxxxxxxx",
|
||||
"roles": [
|
||||
"readonly"
|
||||
],
|
||||
"username": "xxxxxxxxxxxxxxxx"
|
||||
}
|
||||
],
|
||||
"wan": {}
|
||||
}
|
||||
----
|
||||
|
||||
Now build the sample with Gradle and push the application to the platform using `cf push`.
|
||||
|
||||
Once the app is running, check the logs with `cf logs security-app --recent` and you should see output like the
|
||||
following:
|
||||
[source]
|
||||
----
|
||||
Successfully wrote data to region Customers
|
||||
Attempting to read data from region Customers
|
||||
----
|
||||
|
||||
You can also hit the endpoint at
|
||||
https://security-app.apps.{cf-instance}.cf-app.com/message[https://security-app.apps.{cf-instance}.cf-app.com/message],
|
||||
where `{cf-instance}` is replaced with the name of your Cloud Foundry instance, to verify that the application is using
|
||||
SSL.
|
||||
2
spring-geode-samples/boot/security/lombok.config
Normal file
2
spring-geode-samples/boot/security/lombok.config
Normal file
@@ -0,0 +1,2 @@
|
||||
# This file is generated by the 'io.freefair.lombok' Gradle plugin
|
||||
config.stopBubbling = true
|
||||
10
spring-geode-samples/boot/security/manifest.yaml
Normal file
10
spring-geode-samples/boot/security/manifest.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
applications:
|
||||
- name: security-app
|
||||
memory: 768M
|
||||
instances: 1
|
||||
path: ./build/libs/spring-geode-samples-boot-security-1.3.0.BUILD-SNAPSHOT.jar
|
||||
services:
|
||||
- pccServiceOne
|
||||
buildpacks:
|
||||
- https://github.com/cloudfoundry/java-buildpack.git
|
||||
@@ -0,0 +1,22 @@
|
||||
plugins {
|
||||
id "io.freefair.lombok" version "5.0.0-rc2"
|
||||
}
|
||||
|
||||
apply plugin: 'io.spring.convention.spring-sample-boot'
|
||||
|
||||
description = "Spring Geode Sample demonstrating Apache Geode security."
|
||||
|
||||
dependencies {
|
||||
|
||||
compile project(":spring-geode-starter")
|
||||
compile project(":spring-geode-starter-test")
|
||||
|
||||
compile "org.springframework.boot:spring-boot-starter-web"
|
||||
|
||||
compile "org.assertj:assertj-core"
|
||||
compile "org.projectlombok:lombok"
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClassName = 'example.app.security.client.BootGeodeSecurityClientApplication'
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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 example.app.security.client;
|
||||
|
||||
import example.app.security.client.model.Customer;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableClusterConfiguration;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
|
||||
|
||||
/**
|
||||
* The {@link BootGeodeSecurityClientApplication} class is a Spring Boot, Apache Geode {@link ClientCache}
|
||||
* application that configures security.
|
||||
*
|
||||
* @author Patrick Johnson
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @see org.springframework.boot.SpringApplication
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication
|
||||
* @since 1.3.0
|
||||
*/
|
||||
// tag::class[]
|
||||
@SpringBootApplication
|
||||
@EnableClusterConfiguration
|
||||
@EnableEntityDefinedRegions
|
||||
public class BootGeodeSecurityClientApplication {
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(BootGeodeSecurityClientApplication.class)
|
||||
.web(WebApplicationType.SERVLET)
|
||||
.build()
|
||||
.run(args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ApplicationRunner runner(@Qualifier("Customers") Region<Long, Customer> customers) {
|
||||
return args -> {
|
||||
customers.put(2L, Customer.newCustomer(2L, "William Evans"));
|
||||
System.out.println(String.format("Successfully wrote data to region %s", customers.getName()));
|
||||
|
||||
try {
|
||||
System.out.println(String.format("Attempting to read data from region %s", customers.getName()));
|
||||
customers.get(2L);
|
||||
} catch (Exception e) {
|
||||
System.out.println(String.format("Read failed because \"%s\"", e.getCause().getMessage()));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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 example.app.security.client.controller;
|
||||
|
||||
import example.app.security.client.BootGeodeSecurityClientApplication;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* The {@link SecurityController} class is a RestController used by {@link BootGeodeSecurityClientApplication}
|
||||
*
|
||||
* @author Patrick Johnson
|
||||
* @see org.springframework.web.bind.annotation.RestController
|
||||
* @since 1.3.0
|
||||
*/
|
||||
// tag::class[]
|
||||
@RestController
|
||||
public class SecurityController {
|
||||
|
||||
@Autowired
|
||||
Environment env;
|
||||
|
||||
@GetMapping("/message")
|
||||
public String getMessage() {
|
||||
return "I'm using SSL with this keystore: " + env.getProperty("spring.data.gemfire.security.ssl.keystore");
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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 example.app.security.client.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.gemfire.mapping.annotation.Region;
|
||||
|
||||
/**
|
||||
* An Abstract Data Type (ADT) modeling a {@literal Customer}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see Id
|
||||
* @see Region
|
||||
* @since 1.0.0
|
||||
*/
|
||||
// tag::class[]
|
||||
@Region("Customers")
|
||||
@EqualsAndHashCode
|
||||
@ToString(of = "name")
|
||||
@RequiredArgsConstructor(staticName = "newCustomer")
|
||||
public class Customer {
|
||||
|
||||
@Id @NonNull @Getter
|
||||
private Long id;
|
||||
|
||||
@NonNull @Getter
|
||||
private String name;
|
||||
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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 example.app.security.server;
|
||||
|
||||
import org.apache.geode.cache.server.CacheServer;
|
||||
import org.apache.geode.internal.security.shiro.GeodePermissionResolver;
|
||||
import org.apache.shiro.realm.text.PropertiesRealm;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableSecurity;
|
||||
|
||||
/**
|
||||
* The {@link BootGeodeSecurityServerApplication} class is a Spring Boot, Apache Geode {@literal peer}
|
||||
* {@link CacheServer} application serving cache clients.
|
||||
*
|
||||
* This Apache Geode peer member server configures security.
|
||||
*
|
||||
* @author Patrick Johnson
|
||||
* @see org.apache.geode.cache.Cache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.server.CacheServer
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
|
||||
* @since 1.3.0
|
||||
*/
|
||||
// tag::class[]
|
||||
@SpringBootApplication
|
||||
public class BootGeodeSecurityServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(BootGeodeSecurityServerApplication.class)
|
||||
.web(WebApplicationType.NONE)
|
||||
.build()
|
||||
.run(args);
|
||||
}
|
||||
|
||||
@CacheServerApplication
|
||||
@EnableSecurity
|
||||
static class GeodeServerConfig {
|
||||
|
||||
// tag::realm[]
|
||||
@Bean
|
||||
PropertiesRealm shiroRealm() {
|
||||
|
||||
PropertiesRealm propertiesRealm = new PropertiesRealm();
|
||||
|
||||
propertiesRealm.setResourcePath("classpath:shiro.properties");
|
||||
propertiesRealm.setPermissionResolver(new GeodePermissionResolver());
|
||||
|
||||
return propertiesRealm;
|
||||
}
|
||||
// end::realm[]
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Spring Boot client application.properties
|
||||
|
||||
spring.data.gemfire.security.ssl.keystore.password=s3cr3t
|
||||
spring.data.gemfire.security.username = jdoe
|
||||
spring.data.gemfire.security.password = p@55w0rd
|
||||
@@ -0,0 +1,3 @@
|
||||
# assign user jdoe the role fo viewer and give him DATA:WRITE permissions
|
||||
user.jdoe = p@55w0rd, viewer
|
||||
role.viewer = DATA:WRITE
|
||||
Binary file not shown.
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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 example.app.security;
|
||||
|
||||
import example.app.security.client.BootGeodeSecurityClientApplication;
|
||||
import example.app.security.client.model.Customer;
|
||||
import example.app.security.server.BootGeodeSecurityServerApplication;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ServerOperationException;
|
||||
import org.apache.geode.security.NotAuthorizedException;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.data.gemfire.tests.integration.ClientServerIntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.tests.process.ProcessWrapper;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
/**
|
||||
* Integration Tests for {@link BootGeodeSecurityClientApplication} and {@link BootGeodeSecurityServerApplication}.
|
||||
*
|
||||
* @author Patrick Johsnon
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @see example.app.security.client.BootGeodeSecurityClientApplication
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = BootGeodeSecurityClientApplication.class)
|
||||
public class BootGeodeSecurityClientApplicationIntegrationTests extends ClientServerIntegrationTestsSupport {
|
||||
|
||||
private static ProcessWrapper geodeServer;
|
||||
|
||||
@Resource(name = "Customers")
|
||||
private Region<Long, Customer> customers;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() throws IOException {
|
||||
int availablePort = findAvailablePort();
|
||||
|
||||
geodeServer = run(BootGeodeSecurityServerApplication.class,
|
||||
String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort));
|
||||
|
||||
waitForServerToStart("localhost", availablePort);
|
||||
|
||||
System.setProperty(GEMFIRE_POOL_SERVERS_PROPERTY, String.format("%s[%d]", "localhost", availablePort));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dataReadNotAllowed() {
|
||||
Exception exception = assertThrows(ServerOperationException.class, () -> customers.get(2L).getName());
|
||||
assertThat(exception.getCause()).isInstanceOf(NotAuthorizedException.class);
|
||||
assertThat(exception.getCause().getMessage()).contains("jdoe not authorized for DATA:READ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dataWriteAllowed() {
|
||||
customers.put(3L, Customer.newCustomer(3L, "Samantha Rogers"));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanup() {
|
||||
stop(geodeServer);
|
||||
System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user