From 65070275a3eeea86c5ce6707380ece9dfadaae86 Mon Sep 17 00:00:00 2001 From: Nathan Cannon Date: Mon, 8 Oct 2018 11:42:13 +0100 Subject: [PATCH] Added basic authentication on api POST routes. --- backend/pom.xml | 4 + .../co/neviyn/observationdatabase/Security.kt | 72 +++++++++++ .../observationdatabase/ControllerTest.kt | 2 +- frontend/src/views/Home.vue | 2 +- frontend/src/views/NewSite.vue | 118 ++++++++++-------- frontend/src/views/NewTutor.vue | 6 +- 6 files changed, 146 insertions(+), 58 deletions(-) create mode 100644 backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Security.kt diff --git a/backend/pom.xml b/backend/pom.xml index a350ee1..949f29d 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -39,6 +39,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-security + com.fasterxml.jackson.module jackson-module-kotlin diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Security.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Security.kt new file mode 100644 index 0000000..0ff1f16 --- /dev/null +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Security.kt @@ -0,0 +1,72 @@ +package uk.co.neviyn.observationdatabase + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.http.HttpMethod +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.AuthenticationException +import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder +import org.springframework.security.crypto.password.PasswordEncoder +import org.springframework.stereotype.Component +import java.io.IOException +import javax.servlet.ServletException +import javax.servlet.http.HttpServletRequest +import javax.servlet.http.HttpServletResponse + + +@Configuration +@EnableWebSecurity +class CustomWebSecurityConfigurerAdapter : WebSecurityConfigurerAdapter() { + + @Autowired + lateinit var authenticationEntryPoint: MyBasicAuthenticationEntryPoint + + @Autowired + @Throws(Exception::class) + fun configureGlobal(auth: AuthenticationManagerBuilder) { + auth.inMemoryAuthentication() + .withUser("admin").password(passwordEncoder().encode("admin")) + .authorities("ROLE_USER") + } + + @Throws(Exception::class) + override fun configure(http: HttpSecurity) { + http.csrf().disable().authorizeRequests() + .antMatchers(HttpMethod.POST, "/api/**").authenticated() + .anyRequest().permitAll() + .and() + .httpBasic() + .authenticationEntryPoint(authenticationEntryPoint) + .and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) + } + + @Bean + fun passwordEncoder(): PasswordEncoder { + return BCryptPasswordEncoder() + } +} + +@Component +class MyBasicAuthenticationEntryPoint: BasicAuthenticationEntryPoint() { + + @Throws(IOException::class, ServletException::class) + override fun commence + (request: HttpServletRequest, response: HttpServletResponse, authEx: AuthenticationException) { + response.addHeader("WWW-Authenticate", "Basic realm=\"$realmName\"") + response.status = HttpServletResponse.SC_UNAUTHORIZED + response.writer.println("HTTP Status 401 - " + authEx.message) + } + + @Throws + override fun afterPropertiesSet() { + realmName = "Security" + super.afterPropertiesSet() + } +} \ No newline at end of file diff --git a/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/ControllerTest.kt b/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/ControllerTest.kt index 175956a..152de08 100644 --- a/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/ControllerTest.kt +++ b/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/ControllerTest.kt @@ -144,7 +144,7 @@ class ControllerTest { val observation = Observation(1, site, LocalDate.now(), TrainingType.INITIAL, "An Observation", "Group A", 5.0, 5.0, 5.0, .05, 5.0, newData.entries, setOf(tutor)) doReturn(observation).`when`(observationRepository).save(ArgumentMatchers.any()) val result = controller.addObservation(newData) - assertEquals(1, result) + assertEquals(1L, result) } } \ No newline at end of file diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue index 0808487..bd48abc 100644 --- a/frontend/src/views/Home.vue +++ b/frontend/src/views/Home.vue @@ -144,7 +144,7 @@ console.log("submit"); e.preventDefault(); e.stopPropagation(); - var form = document.getElementById("submission-form"); + let form = document.getElementById("submission-form"); if (form.checkValidity()) { this.$router.push("/observation"); } diff --git a/frontend/src/views/NewSite.vue b/frontend/src/views/NewSite.vue index b6b06de..10838ae 100644 --- a/frontend/src/views/NewSite.vue +++ b/frontend/src/views/NewSite.vue @@ -1,59 +1,71 @@ diff --git a/frontend/src/views/NewTutor.vue b/frontend/src/views/NewTutor.vue index a0beef5..4ac8a96 100644 --- a/frontend/src/views/NewTutor.vue +++ b/frontend/src/views/NewTutor.vue @@ -60,7 +60,7 @@ export default { var form = document.getElementById("submission-form"); let axiosConfig = { auth: { - username: "test", + username: "admin", password: this.submissionPassword } }; @@ -69,7 +69,7 @@ export default { .post("/tutor", { 'siteId': this.siteSelection, 'name': this.tutorName - }) + }, axiosConfig) .then(response => { this.alertVariant = "success"; this.alertText = "Successfully added " + response.data.text; @@ -80,7 +80,7 @@ export default { this.alertText = "Failed to add Tutor"; this.showAlert(); console.log(error); - }, axiosConfig); + }); } } }