diff --git a/pom.xml b/pom.xml index 10a2dfa9ba531ac9314aa0feff036124fcf1017e..fd51f1f8e27c36f534f9035ed3c1fa367a0aede6 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,99 @@ <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>com.auth0</groupId> + <artifactId>java-jwt</artifactId> + <version>4.3.0</version> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.springdoc</groupId> + <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> + <version>2.0.2</version> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-jpa</artifactId> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>2.1.214</version> + <scope>runtime</scope> + </dependency> + + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-core</artifactId> + <version>6.4.1.Final</version> + </dependency> + <dependency> + <groupId>org.modelmapper</groupId> + <artifactId>modelmapper</artifactId> + <version>2.4.4</version> + </dependency> + + <dependency> + <groupId>com.auth0</groupId> + <artifactId>java-jwt</artifactId> + <version>4.3.0</version> + </dependency> + + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-test</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + </dependency> + + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt-api</artifactId> + <version>0.11.2</version> + </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt-impl</artifactId> + <version>0.11.2</version> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt-jackson</artifactId> + <version>0.11.2</version> + <scope>runtime</scope> + </dependency> + </dependencies> <build> diff --git a/src/main/java/idatt2106/systemutvikling/sparesti/Controllers/placeholder b/src/main/java/idatt2106/systemutvikling/sparesti/Controllers/placeholder new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/main/java/idatt2106/systemutvikling/sparesti/DAO/placeholder b/src/main/java/idatt2106/systemutvikling/sparesti/DAO/placeholder new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/main/java/idatt2106/systemutvikling/sparesti/DTO/placeholder b/src/main/java/idatt2106/systemutvikling/sparesti/DTO/placeholder new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/main/java/idatt2106/systemutvikling/sparesti/Security/JWTAuthorizationFilter.java b/src/main/java/idatt2106/systemutvikling/sparesti/Security/JWTAuthorizationFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..a6729ff32f4bc837bef41b6bcc49b6175cef3ebf --- /dev/null +++ b/src/main/java/idatt2106/systemutvikling/sparesti/Security/JWTAuthorizationFilter.java @@ -0,0 +1,78 @@ +package idatt2106.systemutvikling.sparesti.Security; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTVerificationException; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; +import java.util.Collections; + +public class JWTAuthorizationFilter extends OncePerRequestFilter { + + private static final Logger LOGGER = LogManager.getLogger(JWTAuthorizationFilter.class); + + @Value("${jwt.secret}") + private String SECRET; + public static final String USER = "USER"; + public static final String ROLE_USER = "ROLE_" + USER; + + + @Override + protected void doFilterInternal( + HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + + final String header = request.getHeader(HttpHeaders.AUTHORIZATION); + if (header == null || !header.startsWith("Bearer ")) { + filterChain.doFilter(request, response); + return; + } + + String token = header.substring(7); + final String username = validateTokenAndGetUserId(token); + if (username == null) { + // validation failed or token expired + filterChain.doFilter(request, response); + return; + } + + // if token is valid, add user details to the authentication context + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken( + username, + null, + Collections.singletonList(new SimpleGrantedAuthority(ROLE_USER))); + SecurityContextHolder.getContext().setAuthentication(auth); + + // then, continue with authenticated user context + filterChain.doFilter(request, response); + } + + + public String validateTokenAndGetUserId(final String token) { + // remove quotes from token as it breaks the verification + String tokenWithoutQuotes = token.replace("\"", ""); + try { + final Algorithm hmac512 = Algorithm.HMAC512(SECRET); + final JWTVerifier verifier = JWT.require(hmac512).build(); + return verifier.verify(tokenWithoutQuotes).getSubject(); + } catch (final JWTVerificationException verificationEx) { + LOGGER.warn("token is invalid: {}", verificationEx.getMessage()); + return null; + } + } + +} \ No newline at end of file diff --git a/src/main/java/idatt2106/systemutvikling/sparesti/Security/SecurityConfig.java b/src/main/java/idatt2106/systemutvikling/sparesti/Security/SecurityConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..e87436cf2c5dcac9fdc5926ccaab55806f0431d7 --- /dev/null +++ b/src/main/java/idatt2106/systemutvikling/sparesti/Security/SecurityConfig.java @@ -0,0 +1,37 @@ +package idatt2106.systemutvikling.sparesti.Security; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +/** + * Configuration class for the security settings. + */ +@Configuration +public class SecurityConfig { + + //placeholder for the filter chain + + /* + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + .csrf().disable() + .cors().and() + .authorizeHttpRequests() + .requestMatchers( + ............ + ).permitAll() + .anyRequest().authenticated().and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + .addFilterBefore(new JWTAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class); + + + + return http.build(); + }*/ + +} diff --git a/src/main/java/idatt2106/systemutvikling/sparesti/Services/placeholder b/src/main/java/idatt2106/systemutvikling/sparesti/Services/placeholder new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f89b32aa94a0c2a157a290b5cdc4af2013b0a284..5a0bafcd300a608a084f5ebcac28ea43f42dc813 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,2 @@ spring.application.name=sparesti +jwt.secret=secret \ No newline at end of file