Skip to content

Commit

Permalink
Updated API to use Auth0
Browse files Browse the repository at this point in the history
  • Loading branch information
kadraman committed Oct 15, 2024
1 parent e5a2da0 commit e6ba75a
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 24 deletions.
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {

ext {
springBootVersion = '2.7.0'
springOauth2Version = '5.7.1'
springLog4jVersion = '2.3.12.RELEASE'
jacksonVersion = '2.13.0'
itextVersion = '7.2.5'
Expand Down Expand Up @@ -67,6 +68,8 @@ dependencies {
implementation "com.warrenstrange:googleauth:1.5.0"
implementation "com.google.zxing:core:3.4.0"
implementation "com.google.zxing:javase:3.4.0"
implementation "org.springframework.security:spring-security-oauth2-resource-server:${springOauth2Version}"
implementation "org.springframework.security:spring-security-oauth2-jose:${springOauth2Version}"
testImplementation "org.hibernate.validator:hibernate-validator:6.1.0.Final"
testImplementation("org.springframework.boot:spring-boot-starter-test:${springBootVersion}") {
exclude group: "com.vaadin.external.google", module:"android-json"
Expand Down Expand Up @@ -107,7 +110,7 @@ project.archivesBaseName = 'iwa'
group = 'com.microfocus.example'
version = '1.0'
description = 'IWA (Insecure Web App) Pharmacy Direct - an insecure web application for use in Fortify demonstrations'
// A JDK 1.8 is needed if the WebInspect Runtime Agent is being used
// A JDK 1.8 is needed if the WebInspect Runtime Agent is being used?
//sourceCompatibility = JavaVersion.VERSION_1_8
//targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_11
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public class ApiMessageController {
@Autowired
private UserService userService;

@Operation(summary = "Finds messages by keyword(s)", description = "Keyword search by %keyword% format", tags = {"message"}, security = @SecurityRequirement(name = "JWT Authentication"))
@Operation(summary = "Finds messages by keyword(s)", description = "Keyword search by %keyword% format", tags = {"messages"}, security = @SecurityRequirement(name = "JWT Authentication"))
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success", content = @Content(array = @ArraySchema(schema = @Schema(implementation = MessageResponse.class)))),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = ApiStatusResponse.class))),
Expand Down Expand Up @@ -92,7 +92,7 @@ public ResponseEntity<List<MessageResponse>> getMessagesByKeywords(
}
}

@Operation(summary = "Find message by Id", description = "Find a message by UUID", tags = {"message"}, security = @SecurityRequirement(name = "JWT Authentication"))
@Operation(summary = "Find message by Id", description = "Find a message by UUID", tags = {"messages"}, security = @SecurityRequirement(name = "JWT Authentication"))
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success", content = @Content(schema = @Schema(implementation = MessageResponse.class))),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = ApiStatusResponse.class))),
Expand Down Expand Up @@ -166,7 +166,7 @@ public ResponseEntity<ApiStatusResponse> deleteMessage(
return new ResponseEntity<>(apiStatusResponse, HttpStatus.OK);
}

@Operation(summary = "Get users unread message count", description = "Get a users unread message count by their UUID", tags = {"message"}, security = @SecurityRequirement(name = "JWT Authentication"))
@Operation(summary = "Get users unread message count", description = "Get a users unread message count by their UUID", tags = {"messages"}, security = @SecurityRequirement(name = "JWT Authentication"))
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success", content = @Content(schema = @Schema(implementation = MessageResponse.class))),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = ApiStatusResponse.class))),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ Insecure Web App (IWA)
@OpenAPIDefinition(info = @Info(
title = "Insecure Web App (IWA) API",
description = "This is the REST API for Insecure Web App (IWA) Pharmacy Direct. You can select a development or production server to test the API. " +
"Most operations require authentication via a user specific JWT token. To retrieve a JWT token for a user you can use the " +
" '/authentication/sign-in' operation below and then copy the value of the 'accessToken' field. This value can then be " +
"entered when you click on the 'Authorize' button or lock icons.",
"This API is protected using JWT Access tokens generated by Auth0 using Client Credentials Flow, although some operations are public, " +
"such as site (All) and products (Read) and reviews (Read).\n" +
"The Client Credentials Flow (defined in OAuth 2.0 RFC 6749, section 4.4) involves an application exchanging its application credentials," +
"such as client ID and client secret, for an access token. To use protected operations you will need to configure your own Auth0 API Application.",
version = "v3"),
servers = @Server(
url = "{protocol}://{environment}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ Insecure Web App (IWA)
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
Expand Down Expand Up @@ -91,20 +93,23 @@ public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}


@Configuration
@Order(1)
public class ApiConfigurationAdapter extends WebSecurityConfigurerAdapter {

private JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("scope");
jwtGrantedAuthoritiesConverter.setAuthorityPrefix("SCOPE_");
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
return jwtAuthenticationConverter;
}

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {

/*http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/test/**").permitAll()
.anyRequest().authenticated();*/

httpSecurity.antMatcher("/api/**")
.authorizeRequests()
.antMatchers("/api/v3/site/**").permitAll()
Expand All @@ -114,19 +119,20 @@ protected void configure(HttpSecurity httpSecurity) throws Exception {
.antMatchers(HttpMethod.GET,"/api/v3/products/**").permitAll()
.antMatchers(HttpMethod.GET, "/api/v3/reviews").permitAll()
.antMatchers(HttpMethod.GET, "/api/v3/reviews/**").permitAll()
.antMatchers(HttpMethod.GET, "/api/**").authenticated()
.antMatchers(HttpMethod.DELETE, "/api/**").hasAnyRole("ADMIN", "API")
.antMatchers(HttpMethod.POST, "/api/**").hasAnyRole("ADMIN", "API")
.antMatchers(HttpMethod.PUT, "/api/**").hasAnyRole("ADMIN", "API")
.antMatchers(HttpMethod.PATCH, "/api/**").hasAnyRole("ADMIN", "API")
.antMatchers(HttpMethod.GET, "/api/**").hasAuthority("SCOPE_read:users")
.antMatchers(HttpMethod.DELETE, "/api/**").hasAuthority("SCOPE_delete:products")
.antMatchers(HttpMethod.POST, "/api/**").hasAuthority("SCOPE_add:products")
.antMatchers(HttpMethod.PUT, "/api/**").hasAuthority("SCOPE_update:products")
.antMatchers(HttpMethod.PATCH, "/api/**").hasAuthority("SCOPE_update:products")
.and().exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//.and().exceptionHandling().authenticationEntryPoint(basicAuthenticationEntryPoint)
.and().exceptionHandling().accessDeniedHandler(apiAccessDeniedHandler)
.and().csrf().disable();

httpSecurity.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
.and().csrf().disable().cors(Customizer.withDefaults())
.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());

//httpSecurity.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);

}

}
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ spring:
jackson:
serialization:
WRITE_DATES_AS_TIMESTAMPS: false
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://dev-ahui5f878pgtbrpr.us.auth0.com/
audiences: https://iwa-api.onfortify.com
mail:
default-encoding: UTF-8
host: localhost
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ spring:
# favicon:
# enabled: false
throw-exception-if-no-handler-found: true
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://dev-ahui5f878pgtbrpr.us.auth0.com/
audiences: https://iwa-api.onfortify.com
jackson:
serialization:
WRITE_DATES_AS_TIMESTAMPS: false
Expand Down
9 changes: 8 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ spring:
# favicon:
# enabled: false
throw-exception-if-no-handler-found: true
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://dev-ahui5f878pgtbrpr.us.auth0.com/
audiences: https://iwa-api.onfortify.com
jackson:
serialization:
WRITE_DATES_AS_TIMESTAMPS: false
Expand Down Expand Up @@ -82,10 +88,10 @@ springdoc:
display-request-duration: true
operations-sorter: alpha
tagsSorter: alpha

# groups-order: DESC
disable-swagger-default-url: true
paths-to-match: /api/**
writer-with-order-by-keys: true
# group-configs:
# - group: application
# paths-to-match: /api/**
Expand All @@ -99,6 +105,7 @@ logging:
com.microfocus: INFO
org.springframework.web: INFO
org.springframework.security: INFO
org.springframework.security.oauth2: DEBUG

app:
name: IWA Pharmacy Direct
Expand Down

0 comments on commit e6ba75a

Please sign in to comment.