Skip to content

Commit 297c4d1

Browse files
committed
Lesson 10: Securing Microservices with Spring Security
1 parent ffb83db commit 297c4d1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1196
-0
lines changed

Diff for: livelessons-parent/pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<properties>
1616
<main.basedir>../..</main.basedir>
1717
<java.version>1.8</java.version>
18+
<spring-security-oauth.version>2.0.6.RELEASE</spring-security-oauth.version>
1819
</properties>
1920
<build>
2021
<plugins>

Diff for: livelessons-security/README.adoc

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
:compat-mode:
2+
= Lesson 10: Securing Microservices With Spring Security
3+
4+
_How to apply security to your microservices._
5+
6+
- link:livelessons-security-basic[Basic Security]
7+
- link:livelessons-security-sso-auth-server[Single Sign On (Server)]
8+
- link:livelessons-security-sso-resource[Single Sign On (Resource)]
9+
- link:livelessons-security-https[HTTPS (TSL/SSL)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://github.com/SpringOne2GX-2014/microservice-security/blob/master/certs/src/test/java/sample/tomcat/X509ApplicationTests.java
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>livelessons</groupId>
7+
<artifactId>livelessons-security</artifactId>
8+
<version>1.0.0-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>livelessons-security-basic</artifactId>
11+
<properties>
12+
<main.basedir>../..</main.basedir>
13+
</properties>
14+
<dependencies>
15+
<dependency>
16+
<groupId>org.apache.httpcomponents</groupId>
17+
<artifactId>httpclient</artifactId>
18+
</dependency>
19+
<dependency>
20+
<groupId>org.springframework.boot</groupId>
21+
<artifactId>spring-boot-starter-web</artifactId>
22+
</dependency>
23+
<dependency>
24+
<groupId>org.springframework.boot</groupId>
25+
<artifactId>spring-boot-starter-security</artifactId>
26+
</dependency>
27+
<dependency>
28+
<groupId>org.springframework.boot</groupId>
29+
<artifactId>spring-boot-starter-actuator</artifactId>
30+
</dependency>
31+
<dependency>
32+
<groupId>org.springframework.boot</groupId>
33+
<artifactId>spring-boot-starter-jdbc</artifactId>
34+
</dependency>
35+
<dependency>
36+
<groupId>com.h2database</groupId>
37+
<artifactId>h2</artifactId>
38+
</dependency>
39+
<dependency>
40+
<groupId>org.springframework.boot</groupId>
41+
<artifactId>spring-boot-starter-test</artifactId>
42+
<scope>test</scope>
43+
</dependency>
44+
</dependencies>
45+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package basic;
2+
3+
import java.sql.ResultSet;
4+
5+
import org.springframework.boot.SpringApplication;
6+
import org.springframework.boot.autoconfigure.SpringBootApplication;
7+
import org.springframework.context.annotation.Bean;
8+
import org.springframework.jdbc.core.JdbcTemplate;
9+
import org.springframework.jdbc.core.RowMapper;
10+
import org.springframework.security.core.authority.AuthorityUtils;
11+
import org.springframework.security.core.userdetails.User;
12+
import org.springframework.security.core.userdetails.UserDetailsService;
13+
14+
/**
15+
* Demonstrates HTTP basic authentication in action. Try to access the resource
16+
* <A href="http://localhost:8080/hi">in your browser</A> and you'll be prompted to supply
17+
* a username and password. You can find some sample usernames and passwords in
18+
* {@code data.sql}. Similarly, if you try to {@code curl http://localhost:8080/hi},
19+
* you'll be prompted for authentication information.
20+
*/
21+
@SpringBootApplication
22+
public class BasicSecurityApplication {
23+
24+
@Bean
25+
public UserDetailsService userDetailsService(JdbcTemplate jdbcTemplate) {
26+
// @formatter:off
27+
RowMapper<User> userRowMapper = (ResultSet rs, int i) -> new User(
28+
rs.getString("ACCOUNT_NAME"),
29+
rs.getString("PASSWORD"),
30+
rs.getBoolean("ENABLED"),
31+
rs.getBoolean("ENABLED"),
32+
rs.getBoolean("ENABLED"),
33+
rs.getBoolean("ENABLED"),
34+
AuthorityUtils.createAuthorityList("ROLE_USER", "ROLE_ADMIN"));
35+
return username -> jdbcTemplate.queryForObject(
36+
"select * from ACCOUNT where ACCOUNT_NAME = ?", userRowMapper, username);
37+
// @formatter:on
38+
}
39+
40+
public static void main(String[] args) {
41+
SpringApplication.run(BasicSecurityApplication.class, args);
42+
}
43+
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package basic;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
6+
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
7+
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
8+
import org.springframework.security.core.userdetails.UserDetailsService;
9+
10+
@Configuration
11+
@EnableGlobalAuthentication
12+
public class CustomGlobalAuthenticationManagerConfiguration
13+
extends GlobalAuthenticationConfigurerAdapter {
14+
15+
@Autowired
16+
private UserDetailsService userDetailsService;
17+
18+
@Override
19+
public void init(AuthenticationManagerBuilder auth) throws Exception {
20+
auth.userDetailsService(this.userDetailsService);
21+
}
22+
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package basic;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.UUID;
6+
7+
import org.springframework.web.bind.annotation.RequestMapping;
8+
import org.springframework.web.bind.annotation.RestController;
9+
10+
@RestController
11+
public class GreetingsRestController {
12+
13+
@RequestMapping("/hi")
14+
public Map<String, Object> hi() {
15+
Map<String, Object> result = new HashMap<>();
16+
result.put("id", UUID.randomUUID().toString());
17+
result.put("content", "Hello, world!");
18+
return result;
19+
}
20+
21+
}

Diff for: livelessons-security/livelessons-security-basic/src/main/resources/application.properties

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- users in system
2+
insert into account(account_name , password) values('jlong', 'spring');
3+
insert into account(account_name , password) values('pwebb', 'boot');
4+
5+
6+
-- oauth client details
7+
insert into client_details( client_id, client_secret, resource_ids, scopes, grant_types, authorities)
8+
values( 'acme' , 'acmesecret', null, 'read', 'authorization_code,refresh_token,password', null );
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
DROP TABLE account if EXISTS ;
2+
DROP TABLE client_details if EXISTS ;
3+
4+
create table account ( ACCOUNT_NAME varchar(255) not null,
5+
PASSWORD varchar(255 ) not null,
6+
ID serial,
7+
ENABLED bool default true) ;
8+
9+
create table client_details(
10+
CLIENT_ID VARCHAR (255) not null unique ,
11+
CLIENT_SECRET VARCHAR (255) not null ,
12+
RESOURCE_IDS VARCHAR (255) null ,
13+
SCOPES VARCHAR (255) null ,
14+
GRANT_TYPES VARCHAR (255) null ,
15+
AUTHORITIES VARCHAR (255) null
16+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package basic;
2+
3+
import org.apache.http.auth.AuthScope;
4+
import org.apache.http.auth.UsernamePasswordCredentials;
5+
import org.apache.http.client.CredentialsProvider;
6+
import org.apache.http.impl.client.BasicCredentialsProvider;
7+
import org.apache.http.impl.client.CloseableHttpClient;
8+
import org.apache.http.impl.client.HttpClientBuilder;
9+
import org.junit.Assert;
10+
import org.junit.Test;
11+
import org.junit.runner.RunWith;
12+
13+
import org.springframework.beans.factory.annotation.Autowired;
14+
import org.springframework.beans.factory.annotation.Value;
15+
import org.springframework.boot.test.SpringApplicationConfiguration;
16+
import org.springframework.boot.test.WebIntegrationTest;
17+
import org.springframework.context.annotation.Bean;
18+
import org.springframework.context.annotation.Configuration;
19+
import org.springframework.http.ResponseEntity;
20+
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
21+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
22+
import org.springframework.web.client.RestTemplate;
23+
24+
@RunWith(SpringJUnit4ClassRunner.class)
25+
@SpringApplicationConfiguration(classes = BasicSecurityApplication.class)
26+
@WebIntegrationTest(randomPort = true)
27+
public class BasicSecurityApplicationTests {
28+
29+
@Value("${local.server.port}")
30+
private int port;
31+
32+
@Autowired
33+
private RestTemplate restTemplate;
34+
35+
@Test
36+
public void contextLoaded() throws Throwable {
37+
ResponseEntity<String> re = restTemplate
38+
.getForEntity("http://localhost:" + port + "/hi", String.class);
39+
String actual = re.getBody().trim().toLowerCase();
40+
Assert.assertTrue(actual.contains("hello"));
41+
System.out.println("received: " + actual);
42+
}
43+
44+
@Configuration
45+
public static class BasicAuthRestTemplateConfig {
46+
47+
private String user = "pwebb", password = "boot";
48+
49+
@Bean
50+
RestTemplate auth() {
51+
// credentials
52+
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(
53+
this.user, this.password);
54+
55+
CredentialsProvider credsProvider = new BasicCredentialsProvider();
56+
credsProvider.setCredentials(AuthScope.ANY, credentials);
57+
58+
// set credentialsProvider on httpClient
59+
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
60+
61+
httpClientBuilder.setDefaultCredentialsProvider(credsProvider);
62+
CloseableHttpClient httpClient = httpClientBuilder.build();
63+
64+
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(
65+
httpClient);
66+
67+
RestTemplate restTemplate = new RestTemplate();
68+
restTemplate.setRequestFactory(factory);
69+
70+
return restTemplate;
71+
}
72+
}
73+
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://github.com/SpringOne2GX-2014/microservice-security/blob/master/certs/src/test/java/sample/tomcat/X509ApplicationTests.java
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>livelessons</groupId>
7+
<artifactId>livelessons-security</artifactId>
8+
<version>1.0.0-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>livelessons-security-https</artifactId>
11+
<properties>
12+
<main.basedir>../..</main.basedir>
13+
</properties>
14+
<dependencies>
15+
<dependency>
16+
<groupId>org.springframework.boot</groupId>
17+
<artifactId>spring-boot-starter-web</artifactId>
18+
</dependency>
19+
<dependency>
20+
<groupId>org.apache.httpcomponents</groupId>
21+
<artifactId>httpclient</artifactId>
22+
<scope>test</scope>
23+
</dependency>
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-starter-security</artifactId>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.springframework.boot</groupId>
30+
<artifactId>spring-boot-starter-actuator</artifactId>
31+
</dependency>
32+
<dependency>
33+
<groupId>org.springframework.boot</groupId>
34+
<artifactId>spring-boot-starter-jdbc</artifactId>
35+
</dependency>
36+
<dependency>
37+
<groupId>com.h2database</groupId>
38+
<artifactId>h2</artifactId>
39+
</dependency>
40+
<dependency>
41+
<groupId>org.springframework.boot</groupId>
42+
<artifactId>spring-boot-starter-test</artifactId>
43+
<scope>test</scope>
44+
</dependency>
45+
</dependencies>
46+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package demo;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
/**
7+
* This example is lifted <a href=
8+
* "https://github.com/SpringOne2GX-2014/microservice-security/blob/master/certs/pom.xml"
9+
* > from Dr. Dave Syer's example on microservice security</a>.
10+
*/
11+
@SpringBootApplication
12+
public class BasicHttpsSecurityApplication {
13+
14+
public static void main(String[] args) {
15+
SpringApplication.run(BasicHttpsSecurityApplication.class, args);
16+
}
17+
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package demo;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.UUID;
6+
7+
import org.springframework.web.bind.annotation.RequestMapping;
8+
import org.springframework.web.bind.annotation.RestController;
9+
10+
@RestController
11+
public class GreetingsRestController {
12+
13+
@RequestMapping("/hi")
14+
public Map<String, Object> hi() {
15+
Map<String, Object> result = new HashMap<>();
16+
result.put("id", UUID.randomUUID().toString());
17+
result.put("content", "Hello, world!");
18+
return result;
19+
}
20+
21+
}

0 commit comments

Comments
 (0)