From e53fdeea86eb11d524d42f74ec293bb982b3b2c0 Mon Sep 17 00:00:00 2001 From: Martin Weise <martin.weise@tuwien.ac.at> Date: Fri, 4 Feb 2022 13:55:23 +0100 Subject: [PATCH] Verify token at each service in the future, assign token upon requests Former-commit-id: a1896f5321fc28bf39dc0d6f2df265bac3edadc1 --- .../at/tuwien/config/WebSecurityConfig.java | 1 - .../src/main/resources/application-docker.yml | 3 +- .../src/main/resources/application.yml | 3 +- .../at/tuwien/config/WebSecurityConfig.java | 67 +++++++++++++++++++ .../exception/AuthenticationException.java | 21 ++++++ .../service/impl/ContainerServiceImpl.java | 8 ++- fda-ui/layouts/default.vue | 24 +------ fda-ui/pages/container/index.vue | 7 +- .../dialogs/Login.vue => pages/login.vue} | 10 +-- .../dialogs/Register.vue => pages/signup.vue} | 4 -- fda-ui/store/index.js | 7 +- 11 files changed, 111 insertions(+), 44 deletions(-) create mode 100644 fda-container-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java create mode 100644 fda-container-service/services/src/main/java/at/tuwien/exception/AuthenticationException.java rename fda-ui/{components/dialogs/Login.vue => pages/login.vue} (90%) rename fda-ui/{components/dialogs/Register.vue => pages/signup.vue} (96%) diff --git a/fda-authentication-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java b/fda-authentication-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java index 40f9c3f70a..e7684780cd 100644 --- a/fda-authentication-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java +++ b/fda-authentication-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java @@ -82,7 +82,6 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { /* set permissions on endpoints */ http.authorizeRequests() /* our public endpoints */ -// .antMatchers("/api/auth**").permitAll() .antMatchers(HttpMethod.POST, "/api/user").permitAll() .antMatchers(HttpMethod.POST, "/api/auth").permitAll() /* our private endpoints */ diff --git a/fda-container-service/rest-service/src/main/resources/application-docker.yml b/fda-container-service/rest-service/src/main/resources/application-docker.yml index 1035559b25..b18fc742b2 100644 --- a/fda-container-service/rest-service/src/main/resources/application-docker.yml +++ b/fda-container-service/rest-service/src/main/resources/application-docker.yml @@ -25,4 +25,5 @@ eureka: instance.hostname: fda-container-service client.serviceUrl.defaultZone: http://fda-discovery-service:9090/eureka/ fda: - ready.path: /ready \ No newline at end of file + ready.path: /ready + auth.url: http://fda-authentication-service:9097/api/auth \ No newline at end of file diff --git a/fda-container-service/rest-service/src/main/resources/application.yml b/fda-container-service/rest-service/src/main/resources/application.yml index 94399f1b0f..98f135bd1e 100644 --- a/fda-container-service/rest-service/src/main/resources/application.yml +++ b/fda-container-service/rest-service/src/main/resources/application.yml @@ -25,4 +25,5 @@ eureka: instance.hostname: fda-container-service client.serviceUrl.defaultZone: http://localhost:9090/eureka/ fda: - ready.path: ./ready \ No newline at end of file + ready.path: ./ready + auth.url: http://localhost:9097/api/auth \ No newline at end of file diff --git a/fda-container-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java b/fda-container-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java new file mode 100644 index 0000000000..9832234740 --- /dev/null +++ b/fda-container-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java @@ -0,0 +1,67 @@ +package at.tuwien.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +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.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +import javax.servlet.http.HttpServletResponse; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${fda.auth.url}") + private String authUrl; + + @Override + protected void configure(HttpSecurity http) throws Exception { + /* enable CORS and disable CSRF */ + http = http.cors().and().csrf().disable(); + /* set session management to stateless */ + http = http + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and(); + /* set unauthorized requests exception handler */ + http = http + .exceptionHandling() + .authenticationEntryPoint( + (request, response, ex) -> { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, + ex.getMessage() + ); + } + ).and(); + /* set permissions on endpoints */ + http.authorizeRequests() + /* our private endpoints */ + .anyRequest().authenticated(); + /* set auth url */ + http.formLogin() + .loginProcessingUrl(authUrl); + } + + @Bean + public CorsFilter corsFilter() { + final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + final CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } + +} diff --git a/fda-container-service/services/src/main/java/at/tuwien/exception/AuthenticationException.java b/fda-container-service/services/src/main/java/at/tuwien/exception/AuthenticationException.java new file mode 100644 index 0000000000..1984387d1e --- /dev/null +++ b/fda-container-service/services/src/main/java/at/tuwien/exception/AuthenticationException.java @@ -0,0 +1,21 @@ +package at.tuwien.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.FORBIDDEN, reason = "Persistence error") +public class AuthenticationException extends Exception { + + public AuthenticationException(String msg) { + super(msg); + } + + public AuthenticationException(String msg, Throwable thr) { + super(msg, thr); + } + + public AuthenticationException(Throwable thr) { + super(thr); + } + +} diff --git a/fda-container-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java b/fda-container-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java index d5afe7b847..3662f91b11 100644 --- a/fda-container-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java +++ b/fda-container-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java @@ -70,7 +70,7 @@ public class ContainerServiceImpl implements ContainerService { container.setPort(availableTcpPort); container.setName(createDto.getName()); container.setInternalName(containerMapper.containerToInternalContainerName(container)); - log.debug("will create host config {} and container {}", hostConfig, container); + log.trace("will create host config {} and container {}", hostConfig, container); /* create the container */ final CreateContainerResponse response; try { @@ -81,8 +81,12 @@ public class ContainerServiceImpl implements ContainerService { .withHostConfig(hostConfig) .exec(); } catch (ConflictException e) { - log.error("conflicting names for container {}, reason: {}", createDto, e.getMessage()); + log.error("Conflicting names {}", createDto.getName()); throw new DockerClientException("Unexpected behavior", e); + } catch (NotFoundException e) { + log.error("The image {}:{} not available on the container service", createDto.getRepository(), createDto.getTag()); + log.debug("payload was {}", createDto); + throw new DockerClientException("Image not available", e); } container.setHash(response.getId()); container = containerRepository.save(container); diff --git a/fda-ui/layouts/default.vue b/fda-ui/layouts/default.vue index fffa3f62a1..b92bb74530 100644 --- a/fda-ui/layouts/default.vue +++ b/fda-ui/layouts/default.vue @@ -31,7 +31,7 @@ <v-btn class="mr-2 white--text" color="blue-grey" - @click="loginDialog = true"> + to="/login"> <v-icon left>mdi-login</v-icon> Login </v-btn> <v-menu bottom offset-y left> @@ -44,7 +44,7 @@ </v-btn> </template> <v-list> - <v-list-item @click="registerDialog = true"> + <v-list-item to="/signup"> <v-list-item-icon> <v-icon left>mdi-account-plus</v-icon> </v-list-item-icon> @@ -79,18 +79,6 @@ </v-card-text> </v-card> </v-footer> - <v-dialog - v-model="loginDialog" - persistent - max-width="640"> - <Login @close="loginDialog = false" /> - </v-dialog> - <v-dialog - v-model="registerDialog" - persistent - max-width="640"> - <Register @close="registerDialog = false" /> - </v-dialog> </v-app> </template> @@ -104,20 +92,12 @@ import { mdiNewspaperVariantOutline, mdiCog } from '@mdi/js' -import Login from '../components/dialogs/Login' -import Register from '../components/dialogs/Register' export default { name: 'DefaultLayout', - components: { - Login, - Register - }, data () { return { drawer: false, - loginDialog: null, - registerDialog: null, items: [ { icon: mdiHome, diff --git a/fda-ui/pages/container/index.vue b/fda-ui/pages/container/index.vue index e28e6c5ffd..fe106920f7 100644 --- a/fda-ui/pages/container/index.vue +++ b/fda-ui/pages/container/index.vue @@ -76,6 +76,9 @@ export default { computed: { loadingColor () { return this.error ? 'red lighten-2' : 'primary' + }, + token () { + return this.$store.state.token } }, mounted () { @@ -86,7 +89,9 @@ export default { this.createDbDialog = false try { this.loading = true - let res = await this.$axios.get('/api/container/') + let res = await this.$axios.get('/api/container/', { + headers: { Authorization: `Bearer ${this.token}` } + }) this.containers = res.data console.debug('containers', this.containers) for (const container of this.containers) { diff --git a/fda-ui/components/dialogs/Login.vue b/fda-ui/pages/login.vue similarity index 90% rename from fda-ui/components/dialogs/Login.vue rename to fda-ui/pages/login.vue index 93c47b7c22..2de5fb7c14 100644 --- a/fda-ui/components/dialogs/Login.vue +++ b/fda-ui/pages/login.vue @@ -30,11 +30,6 @@ </v-card-text> <v-card-actions> <v-spacer /> - <v-btn - class="mb-2" - @click="cancel"> - Cancel - </v-btn> <v-btn id="login" class="mb-2" @@ -69,17 +64,14 @@ export default { beforeMount () { }, methods: { - cancel () { - this.$parent.$parent.$parent.$parent.loginDialog = false - }, async login () { const url = '/api/auth' try { this.loading = true const res = await this.$axios.post(url, this.loginAccount) console.debug('login user', res.data) + this.$store.commit('SET_TOKEN', res.data.token) this.$toast.success('Welcome back!') - this.cancel() } catch (err) { console.error('login user failed', err) this.$toast.error('Failed to login user') diff --git a/fda-ui/components/dialogs/Register.vue b/fda-ui/pages/signup.vue similarity index 96% rename from fda-ui/components/dialogs/Register.vue rename to fda-ui/pages/signup.vue index aac81b1311..8eecba9134 100644 --- a/fda-ui/components/dialogs/Register.vue +++ b/fda-ui/pages/signup.vue @@ -101,9 +101,6 @@ export default { beforeMount () { }, methods: { - cancel () { - this.$parent.$parent.$parent.$parent.registerDialog = false - }, async register () { const url = '/api/user' try { @@ -111,7 +108,6 @@ export default { const res = await this.$axios.post(url, this.createAccount) console.debug('create user', res.data) this.$toast.success('Success. Check your inbox!') - this.cancel() } catch (err) { console.error('create user failed', err) this.$toast.error('Failed to create user') diff --git a/fda-ui/store/index.js b/fda-ui/store/index.js index b9ae5e2b05..a362fb6a48 100644 --- a/fda-ui/store/index.js +++ b/fda-ui/store/index.js @@ -1,12 +1,13 @@ export const state = () => ({ - db: null + db: null, + token: null }) export const mutations = { SET_DATABASE (state, db) { state.db = db }, - SET_THEME (state, theme) { - state.theme = theme + SET_TOKEN (state, token) { + state.token = token } } -- GitLab