From 1fea1bf611afd79c7a6d3fe1097834c37be2ff9b Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Mon, 11 Mar 2024 17:52:07 +0000 Subject: [PATCH] Creating a Spring Security Key for Signing a JWT Token --- .../jwtsignkey/SpringJwtApplication.java | 10 ++ .../controller/JwtAuthController.java | 33 ++++--- .../jwtconfig/AuthEntryPointJwt.java | 28 +++--- .../jwtsignkey/jwtconfig/AuthTokenFilter.java | 60 ++++++------ .../jwtsignkey/jwtconfig/JwtUtils.java | 98 +++++++++++-------- .../jwtsignkey/repository/UserRepository.java | 2 + .../{ => response}/JwtResponse.java | 3 +- .../securityconfig/SecurityConfiguration.java | 29 +++--- .../userservice/UserDetailsImpl.java | 7 -- .../userservice/UserDetailsServiceImpl.java | 18 ++-- .../com/baeldung/request/LoginRequest.java | 24 +++++ .../src/main/resources/application.properties | 3 +- .../JwtSignKeyIntegrationTest.java | 40 ++++++++ 13 files changed, 218 insertions(+), 137 deletions(-) rename spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/{ => response}/JwtResponse.java (95%) create mode 100644 spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/request/LoginRequest.java create mode 100644 spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/jwtsecuritykey/JwtSignKeyIntegrationTest.java diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/SpringJwtApplication.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/SpringJwtApplication.java index 72917323c2..611935e566 100644 --- a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/SpringJwtApplication.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/SpringJwtApplication.java @@ -1,4 +1,14 @@ package com.baeldung.jwtsignkey; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +@SpringBootApplication +@EnableWebMvc public class SpringJwtApplication { + + public static void main(String[] args) { + SpringApplication.run(com.baeldung.jwtsignkey.SpringJwtApplication.class); + } } diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/controller/JwtAuthController.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/controller/JwtAuthController.java index 57b49ec9b8..37de1682db 100644 --- a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/controller/JwtAuthController.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/controller/JwtAuthController.java @@ -3,23 +3,25 @@ package com.baeldung.jwtsignkey.controller; import com.baeldung.jwtsignkey.jwtconfig.JwtUtils; import com.baeldung.jwtsignkey.model.User; import com.baeldung.jwtsignkey.repository.UserRepository; +import com.baeldung.jwtsignkey.response.JwtResponse; import com.baeldung.jwtsignkey.userservice.UserDetailsImpl; +import com.baeldung.request.LoginRequest; import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.web.bind.annotation.CrossOrigin; 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 java.io.UnsupportedEncodingException; -@CrossOrigin(origins = "*", maxAge = 3600) @RestController public class JwtAuthController { @@ -38,8 +40,10 @@ public class JwtAuthController { @PostMapping("/signup") public ResponseEntity registerUser(@RequestBody User signUpRequest, HttpServletRequest request) throws UnsupportedEncodingException { - - // Create new user's account + if (userRepository.existsByUsername(signUpRequest.getUsername())) { + return ResponseEntity.badRequest() + .body("Error: Username is already taken!"); + } User user = new User(); user.setUsername(signUpRequest.getUsername()); user.setPassword(encoder.encode(signUpRequest.getPassword())); @@ -50,21 +54,24 @@ public class JwtAuthController { } @PostMapping("/signin") - public ResponseEntity authenticateUser( @RequestBody LoginRequest loginRequest) { + public ResponseEntity authenticateUser(@RequestBody LoginRequest loginRequest) { - Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword())); + Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword())); - SecurityContextHolder.getContext() - .setAuthentication(authentication); + SecurityContextHolder.getContext() + .setAuthentication(authentication); UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal(); - String jwt = jwtUtils.generateJwtToken(authentication); + String jwt = jwtUtils.generateJwtToken(authentication); - - - return ResponseEntity.ok( - new JwtResponse(jwt, userDetails.getUsername())); + return ResponseEntity.ok(new JwtResponse(jwt, userDetails.getUsername())); } + @RequestMapping("/user-dashboard") + @PreAuthorize("isAuthenticated()") + public String dashboard() { + return "My Dashboard"; + } + } diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/AuthEntryPointJwt.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/AuthEntryPointJwt.java index 1fe3b6aa63..1cc64f3550 100644 --- a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/AuthEntryPointJwt.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/AuthEntryPointJwt.java @@ -18,22 +18,22 @@ import java.util.Map; @Component public class AuthEntryPointJwt implements AuthenticationEntryPoint { - private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class); + private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class); - @Override - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { - logger.error("Unauthorized error: {}", authException.getMessage()); + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { + logger.error("Unauthorized error: {}", authException.getMessage()); - response.setContentType(MediaType.APPLICATION_JSON_VALUE); - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - final Map body = new HashMap<>(); - body.put("status", HttpServletResponse.SC_UNAUTHORIZED); - body.put("error", "Unauthorized"); - body.put("message", authException.getMessage()); - body.put("path", request.getServletPath()); + final Map body = new HashMap<>(); + body.put("status", HttpServletResponse.SC_UNAUTHORIZED); + body.put("error", "Unauthorized"); + body.put("message", authException.getMessage()); + body.put("path", request.getServletPath()); - final ObjectMapper mapper = new ObjectMapper(); - mapper.writeValue(response.getOutputStream(), body); - } + final ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), body); + } } \ No newline at end of file diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/AuthTokenFilter.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/AuthTokenFilter.java index 64dc102cff..a149c71121 100644 --- a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/AuthTokenFilter.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/AuthTokenFilter.java @@ -18,46 +18,42 @@ import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; public class AuthTokenFilter extends OncePerRequestFilter { - @Autowired - private JwtUtils jwtUtils; + @Autowired + private JwtUtils jwtUtils; - @Autowired - private UserDetailsServiceImpl userDetailsService; + @Autowired + private UserDetailsServiceImpl userDetailsService; - private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class); + private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class); - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - try { - String jwt = parseJwt(request); - if (jwt != null && jwtUtils.validateJwtToken(jwt)) { - String username = jwtUtils.getUserNameFromJwtToken(jwt); + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + try { + String jwt = parseJwt(request); + if (jwt != null && jwtUtils.validateJwtToken(jwt)) { + String username = jwtUtils.getUserNameFromJwtToken(jwt); - UserDetails userDetails = userDetailsService.loadUserByUsername(username); - UsernamePasswordAuthenticationToken authentication = - new UsernamePasswordAuthenticationToken( - userDetails, - null, - userDetails.getAuthorities()); - authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - SecurityContextHolder.getContext().setAuthentication(authentication); - } - } catch (Exception e) { - logger.error("Cannot set user authentication: {}", e); + SecurityContextHolder.getContext() + .setAuthentication(authentication); + } + } catch (Exception e) { + logger.error("Cannot set user authentication: {}", e); + } + + filterChain.doFilter(request, response); } - filterChain.doFilter(request, response); - } + private String parseJwt(HttpServletRequest request) { + String headerAuth = request.getHeader("Authorization"); - private String parseJwt(HttpServletRequest request) { - String headerAuth = request.getHeader("Authorization"); + if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) { + return headerAuth.substring(7, headerAuth.length()); + } - if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) { - return headerAuth.substring(7, headerAuth.length()); + return null; } - - return null; - } } diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/JwtUtils.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/JwtUtils.java index a5c3ac9556..44b2128a3b 100644 --- a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/JwtUtils.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/jwtconfig/JwtUtils.java @@ -1,8 +1,13 @@ package com.baeldung.jwtsignkey.jwtconfig; import com.baeldung.jwtsignkey.userservice.UserDetailsImpl; -import io.jsonwebtoken.*; + +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -15,55 +20,62 @@ import java.util.Date; @Component public class JwtUtils { - private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class); + private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class); - @Value("${baeldung.app.jwtSecret}") - private String jwtSecret; + @Value("${baeldung.app.jwtSecret}") + private String jwtSecret; - @Value("${baeldung.app.jwtExpirationMs}") - private int jwtExpirationMs; + @Value("${baeldung.app.jwtExpirationMs}") + private int jwtExpirationMs; - public String generateJwtToken(Authentication authentication) { + public String generateJwtToken(Authentication authentication) { - UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal(); + UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal(); - return Jwts.builder() - .setSubject((userPrincipal.getUsername())) - .setIssuedAt(new Date()) - .setExpiration(new Date((new Date()).getTime() + jwtExpirationMs)) - .signWith(getSigningKey()) - .compact(); + return Jwts.builder() + .subject((userPrincipal.getUsername())) + .issuedAt(new Date()) + .expiration(new Date((new Date()).getTime() + jwtExpirationMs)) + .signWith(getSigningKey()) + .compact(); - } - - private Key getSigningKey() { - byte[] keyBytes = this.jwtSecret.getBytes(StandardCharsets.UTF_8); - return Keys.hmacShaKeyFor(keyBytes); - } - - public String getUserNameFromJwtToken(String token) { - //return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject(); - return Jwts.parser().setSigningKey(getSigningKey()).build().parseClaimsJws(token).getBody().getSubject(); - - } - - public boolean validateJwtToken(String authToken) { - try { - Jwts.parser().setSigningKey(getSigningKey()).build().parseClaimsJws(authToken); - return true; - } catch (SignatureException e) { - logger.error("Invalid JWT signature: {}", e.getMessage()); - } catch (MalformedJwtException e) { - logger.error("Invalid JWT token: {}", e.getMessage()); - } catch (ExpiredJwtException e) { - logger.error("JWT token is expired: {}", e.getMessage()); - } catch (UnsupportedJwtException e) { - logger.error("JWT token is unsupported: {}", e.getMessage()); - } catch (IllegalArgumentException e) { - logger.error("JWT claims string is empty: {}", e.getMessage()); } - return false; - } + private Key getSigningKey() { + byte[] keyBytes = this.jwtSecret.getBytes(StandardCharsets.UTF_8); + return Keys.hmacShaKeyFor(keyBytes); + } + + public String getUserNameFromJwtToken(String token) { + return Jwts.parser() + .setSigningKey(getSigningKey()) + .build() + .parseSignedClaims(token) + .getPayload() + .getSubject(); + + } + + public boolean validateJwtToken(String authToken) { + try { + Jwts.parser() + .setSigningKey(getSigningKey()) + .build() + .parseSignedClaims(authToken); + return true; + } catch (SignatureException e) { + logger.error("Invalid JWT signature: {}", e.getMessage()); + } catch (MalformedJwtException e) { + logger.error("Invalid JWT token: {}", e.getMessage()); + } catch (ExpiredJwtException e) { + logger.error("JWT token is expired: {}", e.getMessage()); + } catch (UnsupportedJwtException e) { + logger.error("JWT token is unsupported: {}", e.getMessage()); + } catch (IllegalArgumentException e) { + logger.error("JWT claims string is empty: {}", e.getMessage()); + } + + return false; + } } diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/repository/UserRepository.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/repository/UserRepository.java index 8d2706f756..886338242c 100644 --- a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/repository/UserRepository.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/repository/UserRepository.java @@ -7,6 +7,8 @@ import java.util.Optional; public interface UserRepository extends JpaRepository { + Boolean existsByUsername(String username); + Optional findByUsername(String username); } diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/JwtResponse.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/response/JwtResponse.java similarity index 95% rename from spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/JwtResponse.java rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/response/JwtResponse.java index 371491d49e..1c367c4999 100644 --- a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/JwtResponse.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/response/JwtResponse.java @@ -1,4 +1,4 @@ -package com.baeldung.jwtsignkey; +package com.baeldung.jwtsignkey.response; public class JwtResponse { private String token; @@ -6,7 +6,6 @@ public class JwtResponse { private String username; - public JwtResponse(String accessToken, String username) { this.token = accessToken; this.username = username; diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/securityconfig/SecurityConfiguration.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/securityconfig/SecurityConfiguration.java index be980966c8..5a83826065 100644 --- a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/securityconfig/SecurityConfiguration.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/securityconfig/SecurityConfiguration.java @@ -3,6 +3,7 @@ package com.baeldung.jwtsignkey.securityconfig; import com.baeldung.jwtsignkey.jwtconfig.AuthEntryPointJwt; import com.baeldung.jwtsignkey.jwtconfig.AuthTokenFilter; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.security.servlet.PathRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; @@ -17,6 +18,8 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS; @@ -30,16 +33,13 @@ public class SecurityConfiguration { @Autowired private AuthEntryPointJwt unauthorizedHandler; - private static final String[] WHITE_LIST_URL = { "/signin", "/signup" - }; + private static final String[] WHITE_LIST_URL = { "/h2-console/**","/signin", "/signup", "/user-dashboard" }; @Bean public AuthTokenFilter authenticationJwtTokenFilter() { return new AuthTokenFilter(); } - - @Bean public DaoAuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); @@ -61,20 +61,19 @@ public class SecurityConfiguration { } @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + public SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception { http.csrf(AbstractHttpConfigurer::disable) - .cors(AbstractHttpConfigurer::disable) - .authorizeHttpRequests(req -> req.requestMatchers(WHITE_LIST_URL) - .permitAll() - .anyRequest() - .authenticated()) - .exceptionHandling( ex -> ex.authenticationEntryPoint(unauthorizedHandler)) - .sessionManagement(session -> session.sessionCreationPolicy(STATELESS)) - .authenticationProvider(authenticationProvider()) - .addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class); + .cors(AbstractHttpConfigurer::disable) + .authorizeHttpRequests(req -> req.requestMatchers(WHITE_LIST_URL) + .permitAll() + .anyRequest() + .authenticated()) + .exceptionHandling(ex -> ex.authenticationEntryPoint(unauthorizedHandler)) + .sessionManagement(session -> session.sessionCreationPolicy(STATELESS)) + .authenticationProvider(authenticationProvider()) + .addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } } - diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/userservice/UserDetailsImpl.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/userservice/UserDetailsImpl.java index 7c145d50c8..a651a1088a 100644 --- a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/userservice/UserDetailsImpl.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/userservice/UserDetailsImpl.java @@ -18,7 +18,6 @@ public class UserDetailsImpl implements UserDetails { @JsonIgnore private String password; - public UserDetailsImpl(Long id, String username, String password) { this.id = id; this.username = username; @@ -28,17 +27,13 @@ public class UserDetailsImpl implements UserDetails { public static UserDetailsImpl build(User user) { - return new UserDetailsImpl(user.getId(), user.getUsername(), user.getPassword()); } - public Long getId() { return id; } - - public static long getSerialversionuid() { return serialVersionUID; } @@ -78,8 +73,6 @@ public class UserDetailsImpl implements UserDetails { return true; } - - @Override public boolean equals(Object o) { if (this == o) diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/userservice/UserDetailsServiceImpl.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/userservice/UserDetailsServiceImpl.java index dcaa4ec716..c544f748cd 100644 --- a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/userservice/UserDetailsServiceImpl.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/jwtsignkey/userservice/UserDetailsServiceImpl.java @@ -14,15 +14,15 @@ import org.springframework.transaction.annotation.Transactional; @Service public class UserDetailsServiceImpl implements UserDetailsService { - @Autowired - UserRepository userRepository; + @Autowired + UserRepository userRepository; - @Override - @Transactional - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - User user = userRepository.findByUsername(username) - .orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username)); + @Override + @Transactional + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + User user = userRepository.findByUsername(username) + .orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username)); - return UserDetailsImpl.build(user); - } + return UserDetailsImpl.build(user); + } } \ No newline at end of file diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/request/LoginRequest.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/request/LoginRequest.java new file mode 100644 index 0000000000..24555136c2 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/request/LoginRequest.java @@ -0,0 +1,24 @@ +package com.baeldung.request; + +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; + } +} diff --git a/spring-security-modules/spring-security-core-2/src/main/resources/application.properties b/spring-security-modules/spring-security-core-2/src/main/resources/application.properties index d6d6a6f507..6005cdd2d2 100644 --- a/spring-security-modules/spring-security-core-2/src/main/resources/application.properties +++ b/spring-security-modules/spring-security-core-2/src/main/resources/application.properties @@ -1,3 +1,2 @@ -spring.thymeleaf.prefix=classpath:/templates/ baeldung.app.jwtSecret= 404E635266556A586E3272357538782F413F4428472B4B6250645367566B5970 -baeldung.app.jwtExpirationMs= 8640000 \ No newline at end of file +baeldung.app.jwtExpirationMs= 8640000 diff --git a/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/jwtsecuritykey/JwtSignKeyIntegrationTest.java b/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/jwtsecuritykey/JwtSignKeyIntegrationTest.java new file mode 100644 index 0000000000..73d1142ceb --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/jwtsecuritykey/JwtSignKeyIntegrationTest.java @@ -0,0 +1,40 @@ +package com.baeldung.jwtsecuritykey; + +import com.baeldung.jwtsignkey.SpringJwtApplication; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest(classes = SpringJwtApplication.class) +public class JwtSignKeyIntegrationTest { + + @Autowired + private WebApplicationContext context; + + private MockMvc mvc; + + @BeforeEach + private void setup() { + mvc = MockMvcBuilders.webAppContextSetup(context) + .apply(springSecurity()) + .build(); + } + + + @Test + public void givenAnonymous_whenAccessUserDashboard_thenForbidden() throws Exception { + mvc.perform(get("/user-dashboard")) + .andExpect(status().isUnauthorized()); + } + + +} +