SlideShare a Scribd company logo
‹#›© 2016 Pivotal Software, Inc. All rights reserved. ‹#›© 2016 Pivotal Software, Inc. All rights reserved.
Spring Boot Tips
Toshiaki Maki (@making)
tmaki@pivotal.io
Spring 2017 Feb
2017-02-27
© 2016 Pivotal Software, Inc. All rights reserved.
Who am I ?
• Toshiaki Maki (@making) https://ik.am
• Sr. Solutions Architect @Pivotal
• Spring ☘ / Cloud Foundry ☁ / Concourse ✈ / BOSH 🐚
bit.ly/hajiboot2
© 2016 Pivotal Software, Inc. All rights reserved.
Spring Boot is ....
• Opinionated Framework on Spring Ecosystem
© 2016 Pivotal Software, Inc. All rights reserved.
Spring Boot is ....
• Opinionated Framework on Spring Ecosystem
Spring Boot Way
© 2016 Pivotal Software, Inc. All rights reserved.
https://goo.gl/Ey1y3X
https://github.com/openenquete/enquete
© 2016 Pivotal Software, Inc. All rights reserved.
enquete.jar
Thymeleaf
SpringData
JPA
Spring Data REST
Spring MVC
MySQL
SpringSecurity
OAuth
Cloud Foundry
© 2016 Pivotal Software, Inc. All rights reserved.
enquete.jar
Thymeleaf
SpringData
JPA
Spring Data REST
Spring MVC
MySQL
SpringSecurity
OAuth
Cloud Foundry
© 2016 Pivotal Software, Inc. All rights reserved.
enquete.jar
Thymeleaf
SpringData
JPA
Spring Data REST
Spring MVC
MySQL
SpringSecurity
OAuth
Cloud Foundry
AJAX / REST
© 2016 Pivotal Software, Inc. All rights reserved.
enquete.jar
Thymeleaf
SpringData
JPA
Spring Data REST
Spring MVC
MySQL
SpringSecurity
OAuth
Cloud Foundry
AJAX / REST
GitHub
© 2016 Pivotal Software, Inc. All rights reserved.
enquete.jar
Thymeleaf
SpringData
JPA
Spring Data REST
Spring MVC
MySQL
SpringSecurity
OAuth
Cloud Foundry
AJAX / REST
GitHub
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Error
© 2016 Pivotal Software, Inc. All rights reserved.
Error
© 2016 Pivotal Software, Inc. All rights reserved.
Error
© 2016 Pivotal Software, Inc. All rights reserved.
Error
© 2016 Pivotal Software, Inc. All rights reserved.
Error
org.springframework.boot.autoconfigure.web.DefaultErrorViewResolver
src/main/resources
/static/error/403.html
404.html
40x.html
500.html
50x.html
© 2016 Pivotal Software, Inc. All rights reserved.
Error
org.springframework.boot.autoconfigure.web.DefaultErrorViewResolver
src/main/resources
/templates/error/403.<ext>
404.<ext>
40x.<ext>
500.<ext>
50x.<ext>
© 2016 Pivotal Software, Inc. All rights reserved.
<table th:if="${@environment.acceptsProfiles('default')}">

<tr>
<th>Status</th><td th:text="${status}"></td>
</tr>

<tr>
<th>Error</th><td th:text="${error}"></td>
</tr>

<tr>
<th>Exception</th><td th:text="${exception}"></td>
</tr>

<tr>
<th>Message</th><td th:text="${message}"></td>
</tr>

</table>
© 2016 Pivotal Software, Inc. All rights reserved.
<table th:if="${@environment.acceptsProfiles('default')}">

<tr>
<th>Status</th><td th:text="${status}"></td>
</tr>

<tr>
<th>Error</th><td th:text="${error}"></td>
</tr>

<tr>
<th>Exception</th><td th:text="${exception}"></td>
</tr>

<tr>
<th>Message</th><td th:text="${message}"></td>
</tr>

</table>
profile default
disabled
© 2016 Pivotal Software, Inc. All rights reserved.
<table th:if="${@environment.acceptsProfiles('default')}">

<tr>
<th>Status</th><td th:text="${status}"></td>
</tr>

<tr>
<th>Error</th><td th:text="${error}"></td>
</tr>

<tr>
<th>Exception</th><td th:text="${exception}"></td>
</tr>

<tr>
<th>Message</th><td th:text="${message}"></td>
</tr>

</table>
profile default
disabled
© 2016 Pivotal Software, Inc. All rights reserved.
<table th:if="...">

<!-- -->
<tr th:if="${trace}">
<th>Trace</th>
<td><pre th:text="${trace}"></pre></td>
</tr>

© 2016 Pivotal Software, Inc. All rights reserved.
<table th:if="...">

<!-- -->
<tr th:if="${trace}">
<th>Trace</th>
<td><pre th:text="${trace}"></pre></td>
</tr>

server.error.include-stacktrace=always
application-default.properties
© 2016 Pivotal Software, Inc. All rights reserved.
<table th:if="...">

<!-- -->
<tr th:if="${trace}">
<th>Trace</th>
<td><pre th:text="${trace}"></pre></td>
</tr>

server.error.include-stacktrace=always
application-default.properties
© 2016 Pivotal Software, Inc. All rights reserved.
@ControllerAdvice(annotations = Controller.class)

public class ErrorControllerAdvice {

@ExceptionHandler(NoSuchElementException.class)

@ResponseStatus(HttpStatus.NOT_FOUND)

public String noSuchEelemtException() {

return "error/404";

}

}
© 2016 Pivotal Software, Inc. All rights reserved.
@ControllerAdvice(annotations = Controller.class)

public class ErrorControllerAdvice {

@ExceptionHandler(NoSuchElementException.class)

@ResponseStatus(HttpStatus.NOT_FOUND)

public String noSuchEelemtException() {

return "error/404";

}

}
© 2016 Pivotal Software, Inc. All rights reserved.
@Autowired Environment env;


@ExceptionHandler(NoSuchElementException.class)

@ResponseStatus(HttpStatus.NOT_FOUND)

public String ex(NoSuchElementException e,
Model model) {
addErrors(e, HttpStatus.NOT_FOUND, model);

return "error/404";

}
© 2016 Pivotal Software, Inc. All rights reserved.
void addErrors(Exception e, HttpStatus status,
Model model) {
if (env.acceptsProfiles("default")) {

StringWriter stackTrace = new StringWriter();

e.printStackTrace(new PrintWriter(stackTrace));

stackTrace.flush();

model.addAttribute("status", status.value());

model.addAttribute("error", status.getReasonPhrase());

model.addAttribute("exception", e.getClass());

model.addAttribute("message", e.getMessage());

model.addAttribute("trace", stackTrace.toString());

}

}
© 2016 Pivotal Software, Inc. All rights reserved.
void addErrors(Exception e, HttpStatus status,
Model model) {
if (env.acceptsProfiles("default")) {

StringWriter stackTrace = new StringWriter();

e.printStackTrace(new PrintWriter(stackTrace));

stackTrace.flush();

model.addAttribute("status", status.value());

model.addAttribute("error", status.getReasonPhrase());

model.addAttribute("exception", e.getClass());

model.addAttribute("message", e.getMessage());

model.addAttribute("trace", stackTrace.toString());

}

}
© 2016 Pivotal Software, Inc. All rights reserved.
Profile
• java -jar app.jar --spring.profiles.active=prod
• java -jar -Dspring.profiles.active=prod app.jar
• export SPRING_PRPFILES_ACTIVE=prod
Cloud Foundry
cloud
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Spring Data REST REST API
<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-rest</artifactId>

</dependency>
© 2016 Pivotal Software, Inc. All rights reserved.
public interface FooRepository
extends CrudRepository<Foo, Long> {


}
Repository --> REST API
© 2016 Pivotal Software, Inc. All rights reserved.
public interface FooRepository
extends CrudRepository<Foo, Long> {


}
Repository --> REST API
GET /foos
POST /foos
GET /foos/{fooId}
PUT /foos/{fooId}
DELETE /foos/{fooId}
PATCH /foos/{fooId}
...
© 2016 Pivotal Software, Inc. All rights reserved.
Repository --> REST API
public interface FooRepository
extends PagingAndSortingRepository<Foo, Long> {


}
© 2016 Pivotal Software, Inc. All rights reserved.
Repository --> REST API
public interface FooRepository
extends PagingAndSortingRepository<Foo, Long> {


}
GET /foos?page={page}
&size={size}&sort={sort}
...
© 2016 Pivotal Software, Inc. All rights reserved.
Repository --> REST API
public interface FooRepository
extends PagingAndSortingRepository<Foo, Long> {
List<Foo> findByName(String name);

}
© 2016 Pivotal Software, Inc. All rights reserved.
Repository --> REST API
public interface FooRepository
extends PagingAndSortingRepository<Foo, Long> {
List<Foo> findByName(String name);

}
GET /foos/search/findByName?name={name}
...
© 2016 Pivotal Software, Inc. All rights reserved.
Repository --> REST API
public interface FooRepository
extends Repository<Foo, Long> {
@RestResource(exported = false)
List<Foo> findBySeminarId(Long seminarId);
Optional<Foo> findOne(Long id);
void save(Foo foo); 

}
© 2016 Pivotal Software, Inc. All rights reserved.
Repository --> REST API
public interface FooRepository
extends Repository<Foo, Long> {
@RestResource(exported = false)
List<Foo> findBySeminarId(Long seminarId);
Optional<Foo> findOne(Long id);
void save(Foo foo); 

} GET /foos/{id}
POST /foos
© 2016 Pivotal Software, Inc. All rights reserved.
RepositoryEventHandler
Traditional
Spring Data REST
Controller Service Repository
Repository EventHandler
© 2016 Pivotal Software, Inc. All rights reserved.
RepositoryEventHandler
@RepositoryEventHandler @Component
public class UsernameEventHandler {
@HandleReforeCreate
void setUsername(UsernameHolder holder) {
String username = SecurityContextHolder
.getContext().getAuthentication()
.getName();
holder.setUsername(username);
}

}
© 2016 Pivotal Software, Inc. All rights reserved.
RepositoryEventHandler
@RepositoryEventHandler @Component
public class UsernameEventHandler {
@HandleReforeCreate
void setUsername(UsernameHolder holder) {
String username = SecurityContextHolder
.getContext().getAuthentication()
.getName();
holder.setUsername(username);
}

}
UserHolder
username
© 2016 Pivotal Software, Inc. All rights reserved.
Bean Validation
@Configuration public class RestConfig
extends RepositoryRestConfigurerAdapter {
private final Validator vldtr;
/* constructor */
@Override
public void configureValidatingRepositoryEventListener(...) {
lstnr.addValidator("beforeCreate", vldtr);
lstnr.addValidator("beforeSave", vldtr);
}
}
© 2016 Pivotal Software, Inc. All rights reserved.
Bean Validation
@Configuration public class RestConfig
extends RepositoryRestConfigurerAdapter {
private final Validator vldtr;
/* constructor */
@Override
public void configureValidatingRepositoryEventListener(...) {
lstnr.addValidator("beforeCreate", vldtr);
lstnr.addValidator("beforeSave", vldtr);
}
}
{
"errors": [{
"entity": "ResponseForSession",
"property": "difficulty",
"invalidValue": null,
"message": "may not be null"
}, {
"entity": "ResponseForSession",
"property": "satisfaction",
"invalidValue": null,
"message": "may not be null"
}
]
}
© 2016 Pivotal Software, Inc. All rights reserved.
Traditional
Spring Data REST
Controller Service Repository
Repository EventHandler
@Transactional
© 2016 Pivotal Software, Inc. All rights reserved.
Traditional
Spring Data REST
Controller Service Repository
Repository EventHandler
@Transactional
RepositoryEntity
Controller
© 2016 Pivotal Software, Inc. All rights reserved.
Traditional
Spring Data REST
Controller Service Repository
Repository EventHandler
@Transactional
RepositoryEntity
Controller
© 2016 Pivotal Software, Inc. All rights reserved.
Traditional
Spring Data REST
Controller Service Repository
Repository EventHandler
@Transactional
RepositoryEntity
Controller
AOP
© 2016 Pivotal Software, Inc. All rights reserved.
• https://blog.ik.am/entries/403
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
CSRF
• Spring Security CSRF
• Ajax / SPA
© 2016 Pivotal Software, Inc. All rights reserved.
CSRF
• Spring Security CSRF
• Ajax / SPA
public class SecurityConfig
extends WebSecurityConfigurerAdapter {

@Override

protected void configure(HttpSecurity http)
throws Exception {

http.csrf().disable()/* ... */;
}
}
© 2016 Pivotal Software, Inc. All rights reserved.
CSRF
• Spring Security CSRF
• Ajax / SPA
public class SecurityConfig
extends WebSecurityConfigurerAdapter {

@Override

protected void configure(HttpSecurity http)
throws Exception {

http.csrf().disable()/* ... */;
}
}
🙅
© 2016 Pivotal Software, Inc. All rights reserved.
$.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone',
_csrf: $('input[name=_csrf]').val()
});
$(document).ajaxSend(function(e, xhr, options) {
var token = $('input[name=_csrf]').val();
xhr.setRequestHeader('X-CSRF-TOKEN', token);
});
OR
© 2016 Pivotal Software, Inc. All rights reserved.
I don't like jQuery 😟
© 2016 Pivotal Software, Inc. All rights reserved.
public class SecurityConfig
extends WebSecurityConfigurerAdapter {
@Override

protected void configure(HttpSecurity http)
throws Exception {

http./* ... * /and().csrf()

.csrfTokenRepository(
CookieCsrfTokenRepository
.withHttpOnlyFalse());

}

}
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
HTTP (_csrf) HTTP
(X-CSRF-TOKEN) CSRF HTTP
( )
© 2016 Pivotal Software, Inc. All rights reserved.
HTTP (_csrf) HTTP
(X-CSRF-TOKEN) CSRF HTTP
( )
HTTP (_csrf) HTTP
(X-XSRF-TOKEN) CSRF
Cookie(name=XSRF-TOKEN, httpOnly)
© 2016 Pivotal Software, Inc. All rights reserved.
Axios
• https://github.com/mzabriskie/axios
• node.js Promise HTTP
• XSRF-TOKEN Cookie HTTP
X-XSRF-TOKEN (AngularJS )
© 2016 Pivotal Software, Inc. All rights reserved.
Axios
• https://github.com/mzabriskie/axios
• node.js Promise HTTP
• XSRF-TOKEN Cookie HTTP
X-XSRF-TOKEN (AngularJS )
axios.post('/response_for_seminar', {
comment: 'Great!',
request: 'Sushi!'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
OAuth2 SSO with GitHub
<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-oauth2</artifactId>

</dependency>
© 2016 Pivotal Software, Inc. All rights reserved.
Authorization Code
(grant_type=authorization_code)
Authorization
Server (GitHub)
Web UI
Resource
Server (GitHub API)
© 2016 Pivotal Software, Inc. All rights reserved.
Authorization Code
(grant_type=authorization_code)
Authorization
Server (GitHub)
Web UI
Resource
Server (GitHub API)
authorize
© 2016 Pivotal Software, Inc. All rights reserved.
Authorization Code
(grant_type=authorization_code)
Authorization
Server (GitHub)
Web UI
Resource
Server (GitHub API)
authorize
redirect
© 2016 Pivotal Software, Inc. All rights reserved.
Authorization Code
(grant_type=authorization_code)
Authorization
Server (GitHub)
Web UI
Resource
Server (GitHub API)
authorize
redirect
code
© 2016 Pivotal Software, Inc. All rights reserved.
Authorization Code
(grant_type=authorization_code)
Authorization
Server (GitHub)
Web UI
Resource
Server (GitHub API)
authorize
redirect
code
code
© 2016 Pivotal Software, Inc. All rights reserved.
Authorization Code
(grant_type=authorization_code)
Authorization
Server (GitHub)
Web UI
Resource
Server (GitHub API)
authorize
redirect
code
code
token
© 2016 Pivotal Software, Inc. All rights reserved.
Authorization Code
(grant_type=authorization_code)
Authorization
Server (GitHub)
Web UI
Resource
Server (GitHub API)
authorize
redirect
code
code
token
token
© 2016 Pivotal Software, Inc. All rights reserved.
Authorization Code
(grant_type=authorization_code)
Authorization
Server (GitHub)
Web UI
Resource
Server (GitHub API)
authorize
redirect
code
code
token
token
response
© 2016 Pivotal Software, Inc. All rights reserved.
@EnableOAuth2Sso
@SpringBootApplication
@EnableOAuth2Sso

public class EnqueteApplication {

public static void main(String[] args) {

SpringApplication.run(EnqueteApplication.class,
args);

}
}
© 2016 Pivotal Software, Inc. All rights reserved.
security.oauth2.client.client-id=xxxxx
security.oauth2.client.client-secret=xxxxx
security.oauth2.client.access-token-
uri=https://github.com/login/oauth/access_token
security.oauth2.client.user-authorization-
uri=https://github.com/login/oauth/authorize

security.oauth2.resource.user-info-uri=https://
api.github.com/user
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
PrincipalExtractor / AuthoritiesExtractor
public interface PrincipalExtractor {

Object extractPrincipal(Map<String, Object> map);
}
public interface AuthoritiesExtractor {

List<GrantedAuthority>
extractAuthorities(Map<String, Object> map);
}
© 2016 Pivotal Software, Inc. All rights reserved.
public EnqUserPrincipalExtractor
implements AuthoritiesExtractor {
@Override

Object extractPrincipal(Map<String, Object> map){
return new EnqUser(map.get("name"),
map.get("email"),
map.get("avatar_url"));
}
}
© 2016 Pivotal Software, Inc. All rights reserved.
public EnqUserPrincipalExtractor
implements AuthoritiesExtractor {
@Override

Object extractPrincipal(Map<String, Object> map){
return new EnqUser(map.get("name"),
map.get("email"),
map.get("avatar_url"));
}
}
security.oauth2.resource.user-info-uri
© 2016 Pivotal Software, Inc. All rights reserved.
public EnqUserAuthoritiesExtractor
implements PrincipalExtractor {
@Override

List<GrantedAuthority>
extractAuthorities(Map<String, Object> map){
return Arrays.asList(
!"making".equals(map.get("login")) ?
new SimpleGrantAuthority("ROLE_USER") :
new SimpleGrantAuthority("ROLE_ADMIN")
)
}
© 2016 Pivotal Software, Inc. All rights reserved.
GitHub OK
Authorization
Server
Web UI
Resource
Server
© 2016 Pivotal Software, Inc. All rights reserved.
GitHub OK
Authorization
Server
Web UI
Resource
Server
authorize
© 2016 Pivotal Software, Inc. All rights reserved.
GitHub OK
Authorization
Server
Web UI
Resource
Server
authorize
redirect
© 2016 Pivotal Software, Inc. All rights reserved.
GitHub OK
Authorization
Server
Web UI
Resource
Server
authorize
redirect
code
© 2016 Pivotal Software, Inc. All rights reserved.
GitHub OK
Authorization
Server
Web UI
Resource
Server
authorize
redirect
code
code
© 2016 Pivotal Software, Inc. All rights reserved.
GitHub OK
Authorization
Server
Web UI
Resource
Server
authorize
redirect
code
code
token
© 2016 Pivotal Software, Inc. All rights reserved.
GitHub OK
Authorization
Server
Web UI
Resource
Server
authorize
redirect
code
code
token
token
© 2016 Pivotal Software, Inc. All rights reserved.
GitHub OK
Authorization
Server
Web UI
Resource
Server
authorize
redirect
code
code
token
token
response
© 2016 Pivotal Software, Inc. All rights reserved.
GitHub OK
Authorization
Server
Web UI
Resource
Server
authorize
redirect
code
code
token
token
response
@EnableAuthorizationServer
@EnableResourceServer
© 2016 Pivotal Software, Inc. All rights reserved.
UI SSO
Authorization
Server
Web UI
Resource
ServerAnother Web UI
© 2016 Pivotal Software, Inc. All rights reserved.
• https://github.com/Pivotal-Japan/spring-security-oauth-
workshop
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
public interface UrlShortenerClient {

String shorten(String longUrl);
}
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
@ConditionalOnProperty
© 2016 Pivotal Software, Inc. All rights reserved.
@Component
@ConditionalOnProperty(name =
"enquete.bitly.access-token")
public BitlyClient
implements UrlShortenerClient {
@Override

String shorten(String longUrl) {
String token = props.getBitly()
.getAccessToken();
/* ... */
}
}
Bit.ly URL
© 2016 Pivotal Software, Inc. All rights reserved.
@Component
@ConditionalOnProperty(name =
"enquete.googl.api-key")
public GooglClient
implements UrlShortenerClient {
@Override

String shorten(String longUrl) {
String apiKey = props.getGoogl().getApiKey();
/* ... */
}
}
Goo.gl URL
© 2016 Pivotal Software, Inc. All rights reserved.
enquete.bitly.access-token=0123456789
enquete.googl.api-key=abcdef
BitlyClient
GooglClient
© 2016 Pivotal Software, Inc. All rights reserved.
@Controller
public SeminarController {
final Optional<UrlShortenerClient> shortener;

@GetMapping("seminars/{seminarId}")

public String list(...) {
shortener.ifPresent(x -> {
String shorten = x.shorten(url);
model.addAttribute("shorten", shorten);
});
/* ... */
}
}
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
enquete.bitly.access-token=0123456789
© 2016 Pivotal Software, Inc. All rights reserved.
enquete.bitly.access-token=0123456789
© 2016 Pivotal Software, Inc. All rights reserved.
enquete.bitly.access-token=0123456789enquete.googl.api-key=abcdef
© 2016 Pivotal Software, Inc. All rights reserved.
enquete.bitly.access-token=0123456789enquete.googl.api-key=abcdef
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
@ConfigurationProperties
@ConfigurationProperties(prefix = "enquete")
@Component @Validated
public class EnqProps {

private Set<String> adminUsers;
private Bitly bitly;
public static class Bitly {

private String accessToken;

}
// setter/getter
}
© 2016 Pivotal Software, Inc. All rights reserved.
Configuration Processor
<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</scope>

</dependency>
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Spring Boot Actuator >= 1.5
• (ROLE_ACTUATOR)
• /info, /health (status )
management.security.enabled=false
application-default.properties
© 2016 Pivotal Software, Inc. All rights reserved.
Spring Boot Actuator >= 1.5
• (ROLE_ACTUATOR)
• /info, /health (status )
management.security.enabled=false
application-default.properties
profile default
disabled
© 2016 Pivotal Software, Inc. All rights reserved.
ROLE_ACTUATOR
public EnqUserAuthoritiesExtractor /* ... */ {
@Override

List<GrantedAuthority>
extractAuthorities(Map<String, Object> map){
return !"making".equals(map.get("login")) ?
asList(new SimpleGrantAuthority("ROLE_USER")) :
asList(new SimpleGrantAuthority("ROLE_ADMIN"),
new SimpleGrantAuthority("ROLE_ACTUATOR"))
}
}
© 2016 Pivotal Software, Inc. All rights reserved.
BeansViz
<dependency>

<groupId>am.ik.beansviz</groupId>

<artifactId>beansviz-spring-boot-actuator</artifactId>

<version>0.1.0</version>
</dependency>
© 2016 Pivotal Software, Inc. All rights reserved.
BeansViz
<dependency>

<groupId>am.ik.beansviz</groupId>

<artifactId>beansviz-spring-boot-actuator</artifactId>

<version>0.1.0</version>
</dependency>
Actuator /beansviz
/beans Graphviz
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
© 2016 Pivotal Software, Inc. All rights reserved.
• https://blog.ik.am/entries/401
© 2016 Pivotal Software, Inc. All rights reserved.
Error
Spring Data REST
CSRF
@EnableOAuth2Sso
@ConditionalOnProperty
Configuration Properties
Spring Boot Actuator
Cloud Foundry Integration
© 2016 Pivotal Software, Inc. All rights reserved.
Check Source code!
https://github.com/openenquete/enquete
© 2016 Pivotal Software, Inc. All rights reserved.
Spring Cloud Services in PWS
• https://content.pivotal.io/blog/building-spring-microservices-
with-cloud-foundrys-new-container-networking-stack
© 2016 Pivotal Software, Inc. All rights reserved.
Check Tutorials!!
•https://github.com/Pivotal-Japan
•https://pivotal-japan.connpass.com/

More Related Content

実例で学ぶ、明日から使えるSpring Boot Tips #jsug

  • 1. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. Spring Boot Tips Toshiaki Maki (@making) [email protected] Spring 2017 Feb 2017-02-27
  • 2. © 2016 Pivotal Software, Inc. All rights reserved. Who am I ? • Toshiaki Maki (@making) https://ik.am • Sr. Solutions Architect @Pivotal • Spring ☘ / Cloud Foundry ☁ / Concourse ✈ / BOSH 🐚 bit.ly/hajiboot2
  • 3. © 2016 Pivotal Software, Inc. All rights reserved. Spring Boot is .... • Opinionated Framework on Spring Ecosystem
  • 4. © 2016 Pivotal Software, Inc. All rights reserved. Spring Boot is .... • Opinionated Framework on Spring Ecosystem Spring Boot Way
  • 5. © 2016 Pivotal Software, Inc. All rights reserved. https://goo.gl/Ey1y3X https://github.com/openenquete/enquete
  • 6. © 2016 Pivotal Software, Inc. All rights reserved. enquete.jar Thymeleaf SpringData JPA Spring Data REST Spring MVC MySQL SpringSecurity OAuth Cloud Foundry
  • 7. © 2016 Pivotal Software, Inc. All rights reserved. enquete.jar Thymeleaf SpringData JPA Spring Data REST Spring MVC MySQL SpringSecurity OAuth Cloud Foundry
  • 8. © 2016 Pivotal Software, Inc. All rights reserved. enquete.jar Thymeleaf SpringData JPA Spring Data REST Spring MVC MySQL SpringSecurity OAuth Cloud Foundry AJAX / REST
  • 9. © 2016 Pivotal Software, Inc. All rights reserved. enquete.jar Thymeleaf SpringData JPA Spring Data REST Spring MVC MySQL SpringSecurity OAuth Cloud Foundry AJAX / REST GitHub
  • 10. © 2016 Pivotal Software, Inc. All rights reserved. enquete.jar Thymeleaf SpringData JPA Spring Data REST Spring MVC MySQL SpringSecurity OAuth Cloud Foundry AJAX / REST GitHub
  • 11. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 12. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 13. © 2016 Pivotal Software, Inc. All rights reserved. Error
  • 14. © 2016 Pivotal Software, Inc. All rights reserved. Error
  • 15. © 2016 Pivotal Software, Inc. All rights reserved. Error
  • 16. © 2016 Pivotal Software, Inc. All rights reserved. Error
  • 17. © 2016 Pivotal Software, Inc. All rights reserved. Error org.springframework.boot.autoconfigure.web.DefaultErrorViewResolver src/main/resources /static/error/403.html 404.html 40x.html 500.html 50x.html
  • 18. © 2016 Pivotal Software, Inc. All rights reserved. Error org.springframework.boot.autoconfigure.web.DefaultErrorViewResolver src/main/resources /templates/error/403.<ext> 404.<ext> 40x.<ext> 500.<ext> 50x.<ext>
  • 19. © 2016 Pivotal Software, Inc. All rights reserved. <table th:if="${@environment.acceptsProfiles('default')}">
 <tr> <th>Status</th><td th:text="${status}"></td> </tr>
 <tr> <th>Error</th><td th:text="${error}"></td> </tr>
 <tr> <th>Exception</th><td th:text="${exception}"></td> </tr>
 <tr> <th>Message</th><td th:text="${message}"></td> </tr>
 </table>
  • 20. © 2016 Pivotal Software, Inc. All rights reserved. <table th:if="${@environment.acceptsProfiles('default')}">
 <tr> <th>Status</th><td th:text="${status}"></td> </tr>
 <tr> <th>Error</th><td th:text="${error}"></td> </tr>
 <tr> <th>Exception</th><td th:text="${exception}"></td> </tr>
 <tr> <th>Message</th><td th:text="${message}"></td> </tr>
 </table> profile default disabled
  • 21. © 2016 Pivotal Software, Inc. All rights reserved. <table th:if="${@environment.acceptsProfiles('default')}">
 <tr> <th>Status</th><td th:text="${status}"></td> </tr>
 <tr> <th>Error</th><td th:text="${error}"></td> </tr>
 <tr> <th>Exception</th><td th:text="${exception}"></td> </tr>
 <tr> <th>Message</th><td th:text="${message}"></td> </tr>
 </table> profile default disabled
  • 22. © 2016 Pivotal Software, Inc. All rights reserved. <table th:if="...">
 <!-- --> <tr th:if="${trace}"> <th>Trace</th> <td><pre th:text="${trace}"></pre></td> </tr>

  • 23. © 2016 Pivotal Software, Inc. All rights reserved. <table th:if="...">
 <!-- --> <tr th:if="${trace}"> <th>Trace</th> <td><pre th:text="${trace}"></pre></td> </tr>
 server.error.include-stacktrace=always application-default.properties
  • 24. © 2016 Pivotal Software, Inc. All rights reserved. <table th:if="...">
 <!-- --> <tr th:if="${trace}"> <th>Trace</th> <td><pre th:text="${trace}"></pre></td> </tr>
 server.error.include-stacktrace=always application-default.properties
  • 25. © 2016 Pivotal Software, Inc. All rights reserved. @ControllerAdvice(annotations = Controller.class)
 public class ErrorControllerAdvice {
 @ExceptionHandler(NoSuchElementException.class)
 @ResponseStatus(HttpStatus.NOT_FOUND)
 public String noSuchEelemtException() {
 return "error/404";
 }
 }
  • 26. © 2016 Pivotal Software, Inc. All rights reserved. @ControllerAdvice(annotations = Controller.class)
 public class ErrorControllerAdvice {
 @ExceptionHandler(NoSuchElementException.class)
 @ResponseStatus(HttpStatus.NOT_FOUND)
 public String noSuchEelemtException() {
 return "error/404";
 }
 }
  • 27. © 2016 Pivotal Software, Inc. All rights reserved. @Autowired Environment env; 
 @ExceptionHandler(NoSuchElementException.class)
 @ResponseStatus(HttpStatus.NOT_FOUND)
 public String ex(NoSuchElementException e, Model model) { addErrors(e, HttpStatus.NOT_FOUND, model);
 return "error/404";
 }
  • 28. © 2016 Pivotal Software, Inc. All rights reserved. void addErrors(Exception e, HttpStatus status, Model model) { if (env.acceptsProfiles("default")) {
 StringWriter stackTrace = new StringWriter();
 e.printStackTrace(new PrintWriter(stackTrace));
 stackTrace.flush();
 model.addAttribute("status", status.value());
 model.addAttribute("error", status.getReasonPhrase());
 model.addAttribute("exception", e.getClass());
 model.addAttribute("message", e.getMessage());
 model.addAttribute("trace", stackTrace.toString());
 }
 }
  • 29. © 2016 Pivotal Software, Inc. All rights reserved. void addErrors(Exception e, HttpStatus status, Model model) { if (env.acceptsProfiles("default")) {
 StringWriter stackTrace = new StringWriter();
 e.printStackTrace(new PrintWriter(stackTrace));
 stackTrace.flush();
 model.addAttribute("status", status.value());
 model.addAttribute("error", status.getReasonPhrase());
 model.addAttribute("exception", e.getClass());
 model.addAttribute("message", e.getMessage());
 model.addAttribute("trace", stackTrace.toString());
 }
 }
  • 30. © 2016 Pivotal Software, Inc. All rights reserved. Profile • java -jar app.jar --spring.profiles.active=prod • java -jar -Dspring.profiles.active=prod app.jar • export SPRING_PRPFILES_ACTIVE=prod Cloud Foundry cloud
  • 31. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 32. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 33. © 2016 Pivotal Software, Inc. All rights reserved. Spring Data REST REST API <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-rest</artifactId>
 </dependency>
  • 34. © 2016 Pivotal Software, Inc. All rights reserved. public interface FooRepository extends CrudRepository<Foo, Long> { 
 } Repository --> REST API
  • 35. © 2016 Pivotal Software, Inc. All rights reserved. public interface FooRepository extends CrudRepository<Foo, Long> { 
 } Repository --> REST API GET /foos POST /foos GET /foos/{fooId} PUT /foos/{fooId} DELETE /foos/{fooId} PATCH /foos/{fooId} ...
  • 36. © 2016 Pivotal Software, Inc. All rights reserved. Repository --> REST API public interface FooRepository extends PagingAndSortingRepository<Foo, Long> { 
 }
  • 37. © 2016 Pivotal Software, Inc. All rights reserved. Repository --> REST API public interface FooRepository extends PagingAndSortingRepository<Foo, Long> { 
 } GET /foos?page={page} &size={size}&sort={sort} ...
  • 38. © 2016 Pivotal Software, Inc. All rights reserved. Repository --> REST API public interface FooRepository extends PagingAndSortingRepository<Foo, Long> { List<Foo> findByName(String name);
 }
  • 39. © 2016 Pivotal Software, Inc. All rights reserved. Repository --> REST API public interface FooRepository extends PagingAndSortingRepository<Foo, Long> { List<Foo> findByName(String name);
 } GET /foos/search/findByName?name={name} ...
  • 40. © 2016 Pivotal Software, Inc. All rights reserved. Repository --> REST API public interface FooRepository extends Repository<Foo, Long> { @RestResource(exported = false) List<Foo> findBySeminarId(Long seminarId); Optional<Foo> findOne(Long id); void save(Foo foo); 
 }
  • 41. © 2016 Pivotal Software, Inc. All rights reserved. Repository --> REST API public interface FooRepository extends Repository<Foo, Long> { @RestResource(exported = false) List<Foo> findBySeminarId(Long seminarId); Optional<Foo> findOne(Long id); void save(Foo foo); 
 } GET /foos/{id} POST /foos
  • 42. © 2016 Pivotal Software, Inc. All rights reserved. RepositoryEventHandler Traditional Spring Data REST Controller Service Repository Repository EventHandler
  • 43. © 2016 Pivotal Software, Inc. All rights reserved. RepositoryEventHandler @RepositoryEventHandler @Component public class UsernameEventHandler { @HandleReforeCreate void setUsername(UsernameHolder holder) { String username = SecurityContextHolder .getContext().getAuthentication() .getName(); holder.setUsername(username); }
 }
  • 44. © 2016 Pivotal Software, Inc. All rights reserved. RepositoryEventHandler @RepositoryEventHandler @Component public class UsernameEventHandler { @HandleReforeCreate void setUsername(UsernameHolder holder) { String username = SecurityContextHolder .getContext().getAuthentication() .getName(); holder.setUsername(username); }
 } UserHolder username
  • 45. © 2016 Pivotal Software, Inc. All rights reserved. Bean Validation @Configuration public class RestConfig extends RepositoryRestConfigurerAdapter { private final Validator vldtr; /* constructor */ @Override public void configureValidatingRepositoryEventListener(...) { lstnr.addValidator("beforeCreate", vldtr); lstnr.addValidator("beforeSave", vldtr); } }
  • 46. © 2016 Pivotal Software, Inc. All rights reserved. Bean Validation @Configuration public class RestConfig extends RepositoryRestConfigurerAdapter { private final Validator vldtr; /* constructor */ @Override public void configureValidatingRepositoryEventListener(...) { lstnr.addValidator("beforeCreate", vldtr); lstnr.addValidator("beforeSave", vldtr); } } { "errors": [{ "entity": "ResponseForSession", "property": "difficulty", "invalidValue": null, "message": "may not be null" }, { "entity": "ResponseForSession", "property": "satisfaction", "invalidValue": null, "message": "may not be null" } ] }
  • 47. © 2016 Pivotal Software, Inc. All rights reserved. Traditional Spring Data REST Controller Service Repository Repository EventHandler @Transactional
  • 48. © 2016 Pivotal Software, Inc. All rights reserved. Traditional Spring Data REST Controller Service Repository Repository EventHandler @Transactional RepositoryEntity Controller
  • 49. © 2016 Pivotal Software, Inc. All rights reserved. Traditional Spring Data REST Controller Service Repository Repository EventHandler @Transactional RepositoryEntity Controller
  • 50. © 2016 Pivotal Software, Inc. All rights reserved. Traditional Spring Data REST Controller Service Repository Repository EventHandler @Transactional RepositoryEntity Controller AOP
  • 51. © 2016 Pivotal Software, Inc. All rights reserved. • https://blog.ik.am/entries/403
  • 52. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 53. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 54. © 2016 Pivotal Software, Inc. All rights reserved. CSRF • Spring Security CSRF • Ajax / SPA
  • 55. © 2016 Pivotal Software, Inc. All rights reserved. CSRF • Spring Security CSRF • Ajax / SPA public class SecurityConfig extends WebSecurityConfigurerAdapter {
 @Override
 protected void configure(HttpSecurity http) throws Exception {
 http.csrf().disable()/* ... */; } }
  • 56. © 2016 Pivotal Software, Inc. All rights reserved. CSRF • Spring Security CSRF • Ajax / SPA public class SecurityConfig extends WebSecurityConfigurerAdapter {
 @Override
 protected void configure(HttpSecurity http) throws Exception {
 http.csrf().disable()/* ... */; } } 🙅
  • 57. © 2016 Pivotal Software, Inc. All rights reserved. $.post('/user', { firstName: 'Fred', lastName: 'Flintstone', _csrf: $('input[name=_csrf]').val() }); $(document).ajaxSend(function(e, xhr, options) { var token = $('input[name=_csrf]').val(); xhr.setRequestHeader('X-CSRF-TOKEN', token); }); OR
  • 58. © 2016 Pivotal Software, Inc. All rights reserved. I don't like jQuery 😟
  • 59. © 2016 Pivotal Software, Inc. All rights reserved. public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override
 protected void configure(HttpSecurity http) throws Exception {
 http./* ... * /and().csrf()
 .csrfTokenRepository( CookieCsrfTokenRepository .withHttpOnlyFalse());
 }
 }
  • 60. © 2016 Pivotal Software, Inc. All rights reserved.
  • 61. © 2016 Pivotal Software, Inc. All rights reserved. HTTP (_csrf) HTTP (X-CSRF-TOKEN) CSRF HTTP ( )
  • 62. © 2016 Pivotal Software, Inc. All rights reserved. HTTP (_csrf) HTTP (X-CSRF-TOKEN) CSRF HTTP ( ) HTTP (_csrf) HTTP (X-XSRF-TOKEN) CSRF Cookie(name=XSRF-TOKEN, httpOnly)
  • 63. © 2016 Pivotal Software, Inc. All rights reserved. Axios • https://github.com/mzabriskie/axios • node.js Promise HTTP • XSRF-TOKEN Cookie HTTP X-XSRF-TOKEN (AngularJS )
  • 64. © 2016 Pivotal Software, Inc. All rights reserved. Axios • https://github.com/mzabriskie/axios • node.js Promise HTTP • XSRF-TOKEN Cookie HTTP X-XSRF-TOKEN (AngularJS ) axios.post('/response_for_seminar', { comment: 'Great!', request: 'Sushi!' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
  • 65. © 2016 Pivotal Software, Inc. All rights reserved.
  • 66. © 2016 Pivotal Software, Inc. All rights reserved.
  • 67. © 2016 Pivotal Software, Inc. All rights reserved.
  • 68. © 2016 Pivotal Software, Inc. All rights reserved.
  • 69. © 2016 Pivotal Software, Inc. All rights reserved.
  • 70. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 71. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 72. © 2016 Pivotal Software, Inc. All rights reserved. OAuth2 SSO with GitHub <dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-oauth2</artifactId>
 </dependency>
  • 73. © 2016 Pivotal Software, Inc. All rights reserved. Authorization Code (grant_type=authorization_code) Authorization Server (GitHub) Web UI Resource Server (GitHub API)
  • 74. © 2016 Pivotal Software, Inc. All rights reserved. Authorization Code (grant_type=authorization_code) Authorization Server (GitHub) Web UI Resource Server (GitHub API) authorize
  • 75. © 2016 Pivotal Software, Inc. All rights reserved. Authorization Code (grant_type=authorization_code) Authorization Server (GitHub) Web UI Resource Server (GitHub API) authorize redirect
  • 76. © 2016 Pivotal Software, Inc. All rights reserved. Authorization Code (grant_type=authorization_code) Authorization Server (GitHub) Web UI Resource Server (GitHub API) authorize redirect code
  • 77. © 2016 Pivotal Software, Inc. All rights reserved. Authorization Code (grant_type=authorization_code) Authorization Server (GitHub) Web UI Resource Server (GitHub API) authorize redirect code code
  • 78. © 2016 Pivotal Software, Inc. All rights reserved. Authorization Code (grant_type=authorization_code) Authorization Server (GitHub) Web UI Resource Server (GitHub API) authorize redirect code code token
  • 79. © 2016 Pivotal Software, Inc. All rights reserved. Authorization Code (grant_type=authorization_code) Authorization Server (GitHub) Web UI Resource Server (GitHub API) authorize redirect code code token token
  • 80. © 2016 Pivotal Software, Inc. All rights reserved. Authorization Code (grant_type=authorization_code) Authorization Server (GitHub) Web UI Resource Server (GitHub API) authorize redirect code code token token response
  • 81. © 2016 Pivotal Software, Inc. All rights reserved. @EnableOAuth2Sso @SpringBootApplication @EnableOAuth2Sso
 public class EnqueteApplication {
 public static void main(String[] args) {
 SpringApplication.run(EnqueteApplication.class, args);
 } }
  • 82. © 2016 Pivotal Software, Inc. All rights reserved. security.oauth2.client.client-id=xxxxx security.oauth2.client.client-secret=xxxxx security.oauth2.client.access-token- uri=https://github.com/login/oauth/access_token security.oauth2.client.user-authorization- uri=https://github.com/login/oauth/authorize
 security.oauth2.resource.user-info-uri=https:// api.github.com/user
  • 83. © 2016 Pivotal Software, Inc. All rights reserved.
  • 84. © 2016 Pivotal Software, Inc. All rights reserved.
  • 85. © 2016 Pivotal Software, Inc. All rights reserved. PrincipalExtractor / AuthoritiesExtractor public interface PrincipalExtractor {
 Object extractPrincipal(Map<String, Object> map); } public interface AuthoritiesExtractor {
 List<GrantedAuthority> extractAuthorities(Map<String, Object> map); }
  • 86. © 2016 Pivotal Software, Inc. All rights reserved. public EnqUserPrincipalExtractor implements AuthoritiesExtractor { @Override
 Object extractPrincipal(Map<String, Object> map){ return new EnqUser(map.get("name"), map.get("email"), map.get("avatar_url")); } }
  • 87. © 2016 Pivotal Software, Inc. All rights reserved. public EnqUserPrincipalExtractor implements AuthoritiesExtractor { @Override
 Object extractPrincipal(Map<String, Object> map){ return new EnqUser(map.get("name"), map.get("email"), map.get("avatar_url")); } } security.oauth2.resource.user-info-uri
  • 88. © 2016 Pivotal Software, Inc. All rights reserved. public EnqUserAuthoritiesExtractor implements PrincipalExtractor { @Override
 List<GrantedAuthority> extractAuthorities(Map<String, Object> map){ return Arrays.asList( !"making".equals(map.get("login")) ? new SimpleGrantAuthority("ROLE_USER") : new SimpleGrantAuthority("ROLE_ADMIN") ) }
  • 89. © 2016 Pivotal Software, Inc. All rights reserved. GitHub OK Authorization Server Web UI Resource Server
  • 90. © 2016 Pivotal Software, Inc. All rights reserved. GitHub OK Authorization Server Web UI Resource Server authorize
  • 91. © 2016 Pivotal Software, Inc. All rights reserved. GitHub OK Authorization Server Web UI Resource Server authorize redirect
  • 92. © 2016 Pivotal Software, Inc. All rights reserved. GitHub OK Authorization Server Web UI Resource Server authorize redirect code
  • 93. © 2016 Pivotal Software, Inc. All rights reserved. GitHub OK Authorization Server Web UI Resource Server authorize redirect code code
  • 94. © 2016 Pivotal Software, Inc. All rights reserved. GitHub OK Authorization Server Web UI Resource Server authorize redirect code code token
  • 95. © 2016 Pivotal Software, Inc. All rights reserved. GitHub OK Authorization Server Web UI Resource Server authorize redirect code code token token
  • 96. © 2016 Pivotal Software, Inc. All rights reserved. GitHub OK Authorization Server Web UI Resource Server authorize redirect code code token token response
  • 97. © 2016 Pivotal Software, Inc. All rights reserved. GitHub OK Authorization Server Web UI Resource Server authorize redirect code code token token response @EnableAuthorizationServer @EnableResourceServer
  • 98. © 2016 Pivotal Software, Inc. All rights reserved. UI SSO Authorization Server Web UI Resource ServerAnother Web UI
  • 99. © 2016 Pivotal Software, Inc. All rights reserved. • https://github.com/Pivotal-Japan/spring-security-oauth- workshop
  • 100. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 101. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 102. © 2016 Pivotal Software, Inc. All rights reserved. public interface UrlShortenerClient {
 String shorten(String longUrl); }
  • 103. © 2016 Pivotal Software, Inc. All rights reserved.
  • 104. © 2016 Pivotal Software, Inc. All rights reserved. @ConditionalOnProperty
  • 105. © 2016 Pivotal Software, Inc. All rights reserved. @Component @ConditionalOnProperty(name = "enquete.bitly.access-token") public BitlyClient implements UrlShortenerClient { @Override
 String shorten(String longUrl) { String token = props.getBitly() .getAccessToken(); /* ... */ } } Bit.ly URL
  • 106. © 2016 Pivotal Software, Inc. All rights reserved. @Component @ConditionalOnProperty(name = "enquete.googl.api-key") public GooglClient implements UrlShortenerClient { @Override
 String shorten(String longUrl) { String apiKey = props.getGoogl().getApiKey(); /* ... */ } } Goo.gl URL
  • 107. © 2016 Pivotal Software, Inc. All rights reserved. enquete.bitly.access-token=0123456789 enquete.googl.api-key=abcdef BitlyClient GooglClient
  • 108. © 2016 Pivotal Software, Inc. All rights reserved. @Controller public SeminarController { final Optional<UrlShortenerClient> shortener;
 @GetMapping("seminars/{seminarId}")
 public String list(...) { shortener.ifPresent(x -> { String shorten = x.shorten(url); model.addAttribute("shorten", shorten); }); /* ... */ } }
  • 109. © 2016 Pivotal Software, Inc. All rights reserved.
  • 110. © 2016 Pivotal Software, Inc. All rights reserved. enquete.bitly.access-token=0123456789
  • 111. © 2016 Pivotal Software, Inc. All rights reserved. enquete.bitly.access-token=0123456789
  • 112. © 2016 Pivotal Software, Inc. All rights reserved. enquete.bitly.access-token=0123456789enquete.googl.api-key=abcdef
  • 113. © 2016 Pivotal Software, Inc. All rights reserved. enquete.bitly.access-token=0123456789enquete.googl.api-key=abcdef
  • 114. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 115. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 116. © 2016 Pivotal Software, Inc. All rights reserved. @ConfigurationProperties @ConfigurationProperties(prefix = "enquete") @Component @Validated public class EnqProps {
 private Set<String> adminUsers; private Bitly bitly; public static class Bitly {
 private String accessToken;
 } // setter/getter }
  • 117. © 2016 Pivotal Software, Inc. All rights reserved. Configuration Processor <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</scope>
 </dependency>
  • 118. © 2016 Pivotal Software, Inc. All rights reserved.
  • 119. © 2016 Pivotal Software, Inc. All rights reserved.
  • 120. © 2016 Pivotal Software, Inc. All rights reserved.
  • 121. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 122. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 123. © 2016 Pivotal Software, Inc. All rights reserved. Spring Boot Actuator >= 1.5 • (ROLE_ACTUATOR) • /info, /health (status ) management.security.enabled=false application-default.properties
  • 124. © 2016 Pivotal Software, Inc. All rights reserved. Spring Boot Actuator >= 1.5 • (ROLE_ACTUATOR) • /info, /health (status ) management.security.enabled=false application-default.properties profile default disabled
  • 125. © 2016 Pivotal Software, Inc. All rights reserved. ROLE_ACTUATOR public EnqUserAuthoritiesExtractor /* ... */ { @Override
 List<GrantedAuthority> extractAuthorities(Map<String, Object> map){ return !"making".equals(map.get("login")) ? asList(new SimpleGrantAuthority("ROLE_USER")) : asList(new SimpleGrantAuthority("ROLE_ADMIN"), new SimpleGrantAuthority("ROLE_ACTUATOR")) } }
  • 126. © 2016 Pivotal Software, Inc. All rights reserved. BeansViz <dependency>
 <groupId>am.ik.beansviz</groupId>
 <artifactId>beansviz-spring-boot-actuator</artifactId>
 <version>0.1.0</version> </dependency>
  • 127. © 2016 Pivotal Software, Inc. All rights reserved. BeansViz <dependency>
 <groupId>am.ik.beansviz</groupId>
 <artifactId>beansviz-spring-boot-actuator</artifactId>
 <version>0.1.0</version> </dependency> Actuator /beansviz /beans Graphviz
  • 128. © 2016 Pivotal Software, Inc. All rights reserved.
  • 129. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 130. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 131. © 2016 Pivotal Software, Inc. All rights reserved. Cloud Foundry Integration
  • 132. © 2016 Pivotal Software, Inc. All rights reserved. Cloud Foundry Integration
  • 133. © 2016 Pivotal Software, Inc. All rights reserved.
  • 134. © 2016 Pivotal Software, Inc. All rights reserved.
  • 135. © 2016 Pivotal Software, Inc. All rights reserved. • https://blog.ik.am/entries/401
  • 136. © 2016 Pivotal Software, Inc. All rights reserved. Error Spring Data REST CSRF @EnableOAuth2Sso @ConditionalOnProperty Configuration Properties Spring Boot Actuator Cloud Foundry Integration
  • 137. © 2016 Pivotal Software, Inc. All rights reserved. Check Source code! https://github.com/openenquete/enquete
  • 138. © 2016 Pivotal Software, Inc. All rights reserved. Spring Cloud Services in PWS • https://content.pivotal.io/blog/building-spring-microservices- with-cloud-foundrys-new-container-networking-stack
  • 139. © 2016 Pivotal Software, Inc. All rights reserved. Check Tutorials!! •https://github.com/Pivotal-Japan •https://pivotal-japan.connpass.com/