FEAT: simple JWT | hardcoded usrname/password
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
26
pom.xml
26
pom.xml
@@ -63,6 +63,32 @@
|
|||||||
<artifactId>hibernate-community-dialects</artifactId>
|
<artifactId>hibernate-community-dialects</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JWT -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>0.12.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>0.12.5</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>0.12.5</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
23
src/main/java/com/mallardromain/hotel/DTO/LoginRequest.java
Normal file
23
src/main/java/com/mallardromain/hotel/DTO/LoginRequest.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package com.mallardromain.hotel.DTO;
|
||||||
|
|
||||||
|
public class LoginRequest {
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
public String getUsername(){
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username){
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword(){
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password){
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.mallardromain.hotel.config;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
import com.mallardromain.hotel.security.JWTFilter;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class SecurityConfig {
|
||||||
|
private final JWTFilter jwtFilter;
|
||||||
|
|
||||||
|
public SecurityConfig(JWTFilter jwtFilter) {
|
||||||
|
this.jwtFilter = jwtFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain securityFilterChain(
|
||||||
|
HttpSecurity http
|
||||||
|
) throws Exception {
|
||||||
|
|
||||||
|
http.csrf(csrf -> csrf.disable())
|
||||||
|
.sessionManagement(session ->
|
||||||
|
session.sessionCreationPolicy(
|
||||||
|
SessionCreationPolicy.STATELESS
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.authorizeHttpRequests(auth -> auth
|
||||||
|
.requestMatchers("/auth/**").permitAll()
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
)
|
||||||
|
.addFilterBefore(
|
||||||
|
jwtFilter,
|
||||||
|
UsernamePasswordAuthenticationFilter.class
|
||||||
|
);
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.mallardromain.hotel.controller;
|
||||||
|
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.mallardromain.hotel.DTO.LoginRequest;
|
||||||
|
import com.mallardromain.hotel.service.JWTService;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/auth")
|
||||||
|
public class AuthController {
|
||||||
|
|
||||||
|
private final JWTService jwtService;
|
||||||
|
|
||||||
|
public AuthController(JWTService jwtService){
|
||||||
|
this.jwtService = jwtService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
public ResponseEntity<?> login(
|
||||||
|
@RequestBody LoginRequest request
|
||||||
|
){
|
||||||
|
//temps test1/2
|
||||||
|
if (
|
||||||
|
request.getUsername().equals("test1")
|
||||||
|
&&
|
||||||
|
request.getPassword().equals("password1")
|
||||||
|
) {
|
||||||
|
String token = jwtService
|
||||||
|
.generateToken(request.getUsername());
|
||||||
|
|
||||||
|
return ResponseEntity.ok(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
request.getUsername().equals("test2")
|
||||||
|
&&
|
||||||
|
request.getPassword().equals("password2")
|
||||||
|
) {
|
||||||
|
String token = jwtService
|
||||||
|
.generateToken(request.getUsername());
|
||||||
|
|
||||||
|
return ResponseEntity.ok(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseEntity.status(401).body("Invalid username/password");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
|
|
||||||
import com.mallardromain.hotel.model.Room;
|
import com.mallardromain.hotel.model.Room;
|
||||||
import com.mallardromain.hotel.repository.RoomRepository;
|
import com.mallardromain.hotel.repository.RoomRepository;
|
||||||
import com.mallardromain.hotel.repository.RoomService;
|
import com.mallardromain.hotel.service.RoomService;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/rooms")
|
@RequestMapping("/rooms")
|
||||||
|
|||||||
6
src/main/java/com/mallardromain/hotel/model/JWT.java
Normal file
6
src/main/java/com/mallardromain/hotel/model/JWT.java
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package com.mallardromain.hotel.model;
|
||||||
|
|
||||||
|
public class JWT {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import jakarta.persistence.*;
|
|||||||
public class Room {
|
public class Room {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
||||||
private String number;
|
private String number;
|
||||||
@@ -19,7 +20,7 @@ public class Room {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Room(Integer id, String number, String status){
|
public Room(Integer id, String number, String status){
|
||||||
this.id = id;
|
//this.id = id; id is/should be generated by the DB
|
||||||
this.number = number;
|
this.number = number;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package com.mallardromain.hotel.security;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
import org.springframework.security.web.authentication.WebAuthenticationDetails;
|
||||||
|
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import com.mallardromain.hotel.service.JWTService;
|
||||||
|
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServlet;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JWTFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private final JWTService jwtService;
|
||||||
|
|
||||||
|
public JWTFilter(JWTService jwtService){
|
||||||
|
this.jwtService = jwtService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
FilterChain filterChain
|
||||||
|
) throws ServletException, IOException {
|
||||||
|
|
||||||
|
String authHeader = request
|
||||||
|
.getHeader("Authorization");
|
||||||
|
|
||||||
|
if ( authHeader == null
|
||||||
|
||
|
||||||
|
!authHeader.startsWith("Bearer ")
|
||||||
|
) {
|
||||||
|
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = authHeader.substring(7);
|
||||||
|
|
||||||
|
if (jwtService.isTockenValid(token)){
|
||||||
|
|
||||||
|
String username = jwtService
|
||||||
|
.extractUsername(token);
|
||||||
|
|
||||||
|
UsernamePasswordAuthenticationToken auth =
|
||||||
|
new UsernamePasswordAuthenticationToken(
|
||||||
|
username,
|
||||||
|
null,
|
||||||
|
Collections.emptyList()
|
||||||
|
);
|
||||||
|
|
||||||
|
auth.setDetails(
|
||||||
|
new WebAuthenticationDetailsSource()
|
||||||
|
.buildDetails(request)
|
||||||
|
);
|
||||||
|
|
||||||
|
SecurityContextHolder.getContext()
|
||||||
|
.setAuthentication(auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.mallardromain.hotel.service;
|
||||||
|
|
||||||
|
import java.security.Key;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
|
import io.jsonwebtoken.security.Keys;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class JWTService {
|
||||||
|
|
||||||
|
private static final String SECRET = "NotHardCodedKeyThatIsAtLeast32CharactersLong!";
|
||||||
|
|
||||||
|
private final Key key = Keys.hmacShaKeyFor(SECRET.getBytes());
|
||||||
|
|
||||||
|
public String generateToken(String username){
|
||||||
|
|
||||||
|
return Jwts.builder()
|
||||||
|
.subject(username)
|
||||||
|
.issuedAt(new Date())
|
||||||
|
.expiration(
|
||||||
|
new Date(System.currentTimeMillis() + 1000 * 60 * 60)
|
||||||
|
)
|
||||||
|
.signWith(key)
|
||||||
|
.compact();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTockenValid(String token){
|
||||||
|
|
||||||
|
try {
|
||||||
|
Jwts.parser()
|
||||||
|
.verifyWith((SecretKey) key)
|
||||||
|
.build()
|
||||||
|
.parseSignedClaims(token);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String extractUsername(String token){
|
||||||
|
|
||||||
|
Claims claims = Jwts.parser()
|
||||||
|
.verifyWith((SecretKey) key)
|
||||||
|
.build()
|
||||||
|
.parseSignedClaims(token)
|
||||||
|
.getPayload();
|
||||||
|
|
||||||
|
return claims.getSubject();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.mallardromain.hotel.repository;
|
package com.mallardromain.hotel.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.mallardromain.hotel.model.Room;
|
import com.mallardromain.hotel.model.Room;
|
||||||
|
import com.mallardromain.hotel.repository.RoomRepository;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
Reference in New Issue
Block a user