Skip to content
This repository has been archived by the owner on Apr 22, 2024. It is now read-only.

Commit

Permalink
Added security with spring-xsuaa and spring-security
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Hassler authored and nenaraab committed Apr 6, 2020
1 parent b6cc7b0 commit 585c7a1
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 90 deletions.
3 changes: 2 additions & 1 deletion localEnvironmentSetup.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ REM This script prepares the current shell's environment variables (not permanen

REM Used for backing services like the PostgreSQL database
SET VCAP_APPLICATION={}
SET VCAP_SERVICES={"postgresql-9.3":[{"name":"postgresql-lite","label":"postgresql-9.3","credentials":{"dbname":"test","hostname":"127.0.0.1","password":"test123!","port":"5432","uri":"postgres://testuser:test123!@localhost:5432/test","username":"testuser"},"tags":["relational","postgresql"],"plan":"free"}]}

SET VCAP_SERVICES={"postgresql-9.3":[{"name":"postgresql-lite","label":"postgresql-9.3","credentials":{"dbname":"test","hostname":"127.0.0.1","password":"test123!","port":"5432","uri":"postgres://testuser:test123!@localhost:5432/test","username":"testuser"},"tags":["relational","postgresql"],"plan":"free"}],"xsuaa":[{"credentials":{"clientid":"sb-clientId!t0815","clientsecret":"dummy-clientsecret","identityzone":"<<your tenant>>","identityzoneid":"a09a3440-1da8-4082-a89c-3cce186a9b6c","tenantid":"a09a3440-1da8-4082-a89c-3cce186a9b6c","uaadomain":"localhost","tenantmode":"shared","url":"dummy-url","verificationkey":"-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm1QaZzMjtEfHdimrHP3/2Yr+1z685eiOUlwybRVG9i8wsgOUh+PUGuQL8hgulLZWXU5MbwBLTECAEMQbcRTNVTolkq4i67EP6JesHJIFADbK1Ni0KuMcPuiyOLvDKiDEMnYG1XP3X3WCNfsCVT9YoU+lWIrZr/ZsIvQri8jczr4RkynbTBsPaAOygPUlipqDrpadMO1momNCbea/o6GPn38LxEw609ItfgDGhL6f/yVid5pFzZQWb+9l6mCuJww0hnhO6gt6Rv98OWDty9G0frWAPyEfuIW9B+mR/2vGhyU9IbbWpvFXiy9RVbbsM538TCjd5JF2dJvxy24addC4oQIDAQAB-----END PUBLIC KEY-----","xsappname":"xsapp!t0815"},"label":"xsuaa","name":"uaa-bulletinboard","plan":"application","tags":["xsuaa"]}]}

REM Used for dependent service call
SET USER_ROUTE=https://opensapcp5userservice.cfapps.eu10.hana.ondemand.com
Expand Down
3 changes: 2 additions & 1 deletion localEnvironmentSetup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ echo "This script prepares the current shell's environment variables (not perman

# Used for backing services like the PostgreSQL database
export VCAP_APPLICATION={}
export VCAP_SERVICES='{"postgresql-9.3":[{"name":"postgresql-lite","label":"postgresql-9.3","credentials":{"dbname":"test","hostname":"127.0.0.1","password":"test123!","port":"5432","uri":"postgres://testuser:test123!@localhost:5432/test","username":"testuser"},"tags":["relational","postgresql"],"plan":"free"}]}'

export VCAP_SERVICES='{"postgresql-9.3":[{"name":"postgresql-lite","label":"postgresql-9.3","credentials":{"dbname":"test","hostname":"127.0.0.1","password":"test123!","port":"5432","uri":"postgres://testuser:test123!@localhost:5432/test","username":"testuser"},"tags":["relational","postgresql"],"plan":"free"}],"xsuaa":[{"credentials":{"clientid":"sb-clientId!t0815","clientsecret":"dummy-clientsecret","identityzone":"<<your tenant>>","identityzoneid":"a09a3440-1da8-4082-a89c-3cce186a9b6c","tenantid":"a09a3440-1da8-4082-a89c-3cce186a9b6c","uaadomain":"localhost","tenantmode":"shared","url":"dummy-url","verificationkey":"-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm1QaZzMjtEfHdimrHP3/2Yr+1z685eiOUlwybRVG9i8wsgOUh+PUGuQL8hgulLZWXU5MbwBLTECAEMQbcRTNVTolkq4i67EP6JesHJIFADbK1Ni0KuMcPuiyOLvDKiDEMnYG1XP3X3WCNfsCVT9YoU+lWIrZr/ZsIvQri8jczr4RkynbTBsPaAOygPUlipqDrpadMO1momNCbea/o6GPn38LxEw609ItfgDGhL6f/yVid5pFzZQWb+9l6mCuJww0hnhO6gt6Rv98OWDty9G0frWAPyEfuIW9B+mR/2vGhyU9IbbWpvFXiy9RVbbsM538TCjd5JF2dJvxy24addC4oQIDAQAB-----END PUBLIC KEY-----","xsappname":"xsapp!t0815"},"label":"xsuaa","name":"uaa-bulletinboard","plan":"application","tags":["xsuaa"]}]}'

# Used for dependent service call
export USER_ROUTE=https://opensapcp5userservice.cfapps.eu10.hana.ondemand.com
Expand Down
5 changes: 3 additions & 2 deletions manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ applications:
host: bulletinboard-ads-<<your user id>>
memory: 800M
path: target/bulletinboard-ads.war
buildpack: https://github.com/cloudfoundry/java-buildpack.git#v4.26
buildpack: https://github.com/cloudfoundry/java-buildpack.git
# buildpack: sap_java_buildpack
# health-check-type: http
# health-check-http-endpoint: /health
Expand All @@ -18,11 +18,12 @@ applications:
services:
- postgres-bulletinboard-ads
- applogs-bulletinboard
- uaa-bulletinboard

- name: approuter
host: approuter-<<your user id>>
path: src/main/approuter
buildpack: https://github.com/cloudfoundry/nodejs-buildpack.git#v1.7.9
buildpack: https://github.com/cloudfoundry/nodejs-buildpack.git
memory: 128M
env:
XSAPPNAME: bulletinboard-<<your user id>>
Expand Down
30 changes: 30 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<sap.logging.version>2.1.1</sap.logging.version>
<spring.version>5.2.4.RELEASE</spring.version>
<httpclient.version>4.5.2</httpclient.version>
<spring-security.version>5.2.2.RELEASE</spring-security.version>
<sap.cloud.security.version>2.6.0</sap.cloud.security.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -161,6 +163,28 @@
<version>1.5.10</version>
</dependency>

<!-- Security -->
<dependency> <!-- includes spring-security-oauth2 -->
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>com.sap.cloud.security.xsuaa</groupId>
<artifactId>spring-xsuaa</artifactId>
<version>${sap.cloud.security.version}</version>
</dependency>

<!-- Testing -->
<dependency>
<groupId>org.hamcrest</groupId>
Expand Down Expand Up @@ -200,6 +224,12 @@
<version>1.4.184</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sap.cloud.security</groupId>
<artifactId>java-security-test</artifactId>
<version>${sap.cloud.security.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>bulletinboard-ads</finalName>
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/sap/bulletinboard/ads/AppInitializer.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.sap.bulletinboard.ads;

import java.util.EnumSet;

import javax.servlet.DispatcherType;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.DispatcherServlet;

import com.sap.bulletinboard.ads.config.WebAppContextConfig;
Expand Down Expand Up @@ -35,6 +40,12 @@ public void onStartup(ServletContext servletContext) throws ServletException {
// register logging servlet filter which logs HTTP request processing details
servletContext.addFilter("RequestLoggingFilter", RequestLoggingFilter.class).addMappingForUrlPatterns(null,
false, "/*");

// register filter with name "springSecurityFilterChain"
servletContext
.addFilter(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME,
new DelegatingFilterProxy(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME))
.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.sap.bulletinboard.ads.config;


import com.sap.cloud.security.xsuaa.XsuaaServiceConfiguration;
import com.sap.cloud.security.xsuaa.XsuaaServiceConfigurationDefault;
import com.sap.cloud.security.xsuaa.XsuaaServicePropertySourceFactory;
import com.sap.cloud.security.xsuaa.token.TokenAuthenticationConverter;
import com.sap.cloud.security.xsuaa.token.authentication.XsuaaJwtDecoderBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;

import static org.springframework.http.HttpMethod.*;

@Configuration
@EnableWebSecurity
@PropertySource(factory = XsuaaServicePropertySourceFactory.class, value = { "" })
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

public static final String DISPLAY_SCOPE_LOCAL = "Display";
public static final String UPDATE_SCOPE_LOCAL = "Update";

@Autowired
XsuaaServiceConfiguration xsuaaServiceConfiguration;


// configure Spring Security, demand authentication and specific scopes
@Override
public void configure(HttpSecurity http) throws Exception {

// @formatter:off
http
.sessionManagement()
// session is created by approuter
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
// demand specific scopes depending on intended request
.authorizeRequests()
.antMatchers(GET, "/health", "/").permitAll() //used as health check on CF: must be accessible by "anybody"
.antMatchers(POST, "/api/v1/ads/**").hasAuthority(UPDATE_SCOPE_LOCAL)
.antMatchers(PUT, "/api/v1/ads/**").hasAuthority(UPDATE_SCOPE_LOCAL)
.antMatchers(DELETE, "/api/v1/ads/**").hasAuthority(UPDATE_SCOPE_LOCAL)
.antMatchers(GET, "/api/v1/ads/**").hasAuthority(DISPLAY_SCOPE_LOCAL)
.anyRequest().denyAll() // deny anything not configured above
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(getJwtAuthenticationConverter());
// @formatter:on
}

@Bean
JwtDecoder jwtDecoder() {
return new XsuaaJwtDecoderBuilder(xsuaaServiceConfiguration).build();
}

@Bean
@ConditionalOnMissingBean(XsuaaServiceConfiguration.class)
public XsuaaServiceConfiguration xsuaaServiceConfiguration() {
return new XsuaaServiceConfigurationDefault();
}

/**
* Customizes how GrantedAuthority are derived from a Jwt
*/
Converter<Jwt, AbstractAuthenticationToken> getJwtAuthenticationConverter() {
TokenAuthenticationConverter converter = new TokenAuthenticationConverter(xsuaaServiceConfiguration);
converter.setLocalScopeAsAuthorities(true);
return converter;
}

}
Loading

0 comments on commit 585c7a1

Please sign in to comment.