Skip to content

Commit

Permalink
Update to version 2.2.1. Integrate OpenAPI doc.
Browse files Browse the repository at this point in the history
  • Loading branch information
czetsuya committed Nov 21, 2019
1 parent 7a22602 commit b9728bc
Show file tree
Hide file tree
Showing 6 changed files with 253 additions and 197 deletions.
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,29 @@

A demo project created to demonstrate how a Spring project can be secured using a Keycloak server via bearer token.

Requirements:
SpringDoc URLs:

- springdoc.api-docs=/api-docs
- springdoc.swagger-ui.path=/swagger-ui.html

## Requirements:

- Keycloak server 6.0.1
- https://github.com/czetsuya/keycloak-react

Note:
## Note:

- Make sure that you have the same Keycloak client credentials value for the 2 project ands Keycloak server.

If keycloak.json file is to be used instead of application.yml, set the following system variable and make sure that you have the file keycloak.json in src/main/resources.

keycloak.configurationFile = classpath:keycloak.json

Users
## Users

Role=User, kerri / kerri
Role=Admin, admin / admin
Role=Admin, admin / admin

## References

- https://github.com/springdoc/springdoc-openapi-maven-plugin
34 changes: 33 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<version>2.2.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.broodcamp</groupId>
Expand Down Expand Up @@ -54,6 +54,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand Down Expand Up @@ -108,6 +113,33 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>post-integration-test</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-maven-plugin</artifactId>
<version>0.2</version>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Expand Down
192 changes: 100 additions & 92 deletions src/main/java/com/broodcamp/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,100 +34,108 @@
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

private final KeycloakClientRequestFactory keycloakClientRequestFactory;

public SecurityConfig(KeycloakClientRequestFactory keycloakClientRequestFactory) {
this.keycloakClientRequestFactory = keycloakClientRequestFactory;

// to use principal and authentication together with @async
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}

@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate keycloakRestTemplate() {
return new KeycloakRestTemplate(keycloakClientRequestFactory);
}

public SimpleAuthorityMapper grantedAuthority() {
SimpleAuthorityMapper mapper = new SimpleAuthorityMapper();
mapper.setConvertToUpperCase(true);
return mapper;
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthority());
auth.authenticationProvider(keycloakAuthenticationProvider);
}

@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}

/**
* Use NullAuthenticatedSessionStrategy for bearer-only tokens. Otherwise, use
* RegisterSessionAuthenticationStrategy.
*/
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new NullAuthenticatedSessionStrategy();
}

/**
* Secure appropriate endpoints
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.cors() //
.and() //
.csrf().disable() //
private final KeycloakClientRequestFactory keycloakClientRequestFactory;

public SecurityConfig(KeycloakClientRequestFactory keycloakClientRequestFactory) {
this.keycloakClientRequestFactory = keycloakClientRequestFactory;

// to use principal and authentication together with @async
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}

@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate keycloakRestTemplate() {
return new KeycloakRestTemplate(keycloakClientRequestFactory);
}

public SimpleAuthorityMapper grantedAuthority() {
SimpleAuthorityMapper mapper = new SimpleAuthorityMapper();
mapper.setConvertToUpperCase(true);
return mapper;
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthority());
auth.authenticationProvider(keycloakAuthenticationProvider);
}

@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}

/**
* Use NullAuthenticatedSessionStrategy for bearer-only tokens. Otherwise, use
* RegisterSessionAuthenticationStrategy.
*/
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new NullAuthenticatedSessionStrategy();
}

/**
* Secure appropriate endpoints
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.cors() //
.and() //
.csrf().disable() //
// .anonymous().disable() //
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) //
.and() //
.authorizeRequests() //
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) //
.and() //
.authorizeRequests() //
// .antMatchers("/users*").hasRole("USER") //
// .antMatchers("/admin*").hasRole("ADMIN") //
.anyRequest().permitAll(); //
}

@Bean
public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(KeycloakAuthenticationProcessingFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}

@Bean
public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(KeycloakPreAuthActionsFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}

@Bean
public FilterRegistrationBean keycloakAuthenticatedActionsFilterBean(KeycloakAuthenticatedActionsFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}

@Bean
public FilterRegistrationBean keycloakSecurityContextRequestFilterBean(KeycloakSecurityContextRequestFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}

@Bean
@Override
@ConditionalOnMissingBean(HttpSessionManager.class)
protected HttpSessionManager httpSessionManager() {
return new HttpSessionManager();
}
.anyRequest().permitAll(); //
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(KeycloakAuthenticationProcessingFilter filter) {

FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(KeycloakPreAuthActionsFilter filter) {

FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
public FilterRegistrationBean keycloakAuthenticatedActionsFilterBean(KeycloakAuthenticatedActionsFilter filter) {

FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
public FilterRegistrationBean keycloakSecurityContextRequestFilterBean(KeycloakSecurityContextRequestFilter filter) {

FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}

@Bean
@Override
@ConditionalOnMissingBean(HttpSessionManager.class)
protected HttpSessionManager httpSessionManager() {
return new HttpSessionManager();
}

}
Loading

0 comments on commit b9728bc

Please sign in to comment.