Implement jwt base
This commit is contained in:
@@ -8,27 +8,27 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
@Configuration
|
//@Configuration
|
||||||
public class AppConfig {
|
//public class AppConfig {
|
||||||
private final UserRepository userRepository;
|
// private final UserRepository userRepository;
|
||||||
private final PasswordEncoder bCryptPasswordEncoder;
|
// private final PasswordEncoder bCryptPasswordEncoder;
|
||||||
|
//
|
||||||
public AppConfig(UserRepository userRepository, PasswordEncoder bCryptPasswordEncoder) {
|
// public AppConfig(UserRepository userRepository, PasswordEncoder bCryptPasswordEncoder) {
|
||||||
System.out.println("AppConfig");
|
// System.out.println("AppConfig");
|
||||||
System.out.println("userRepository = " + userRepository);
|
// System.out.println("userRepository = " + userRepository);
|
||||||
this.userRepository = userRepository;
|
// this.userRepository = userRepository;
|
||||||
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
|
// this.bCryptPasswordEncoder = bCryptPasswordEncoder;
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public UserService userService() {
|
|
||||||
System.out.println("userService");
|
|
||||||
return new UserServiceImpl(userRepository, bCryptPasswordEncoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Bean
|
|
||||||
// public BCryptPasswordEncoder passwordEncoder() {
|
|
||||||
// System.out.println("passwordEncoder");
|
|
||||||
// return new BCryptPasswordEncoder();
|
|
||||||
// }
|
// }
|
||||||
}
|
//
|
||||||
|
// @Bean
|
||||||
|
// public UserService userService() {
|
||||||
|
// System.out.println("userService");
|
||||||
|
// return new UserServiceImpl(userRepository, bCryptPasswordEncoder);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//// @Bean
|
||||||
|
//// public BCryptPasswordEncoder passwordEncoder() {
|
||||||
|
//// System.out.println("passwordEncoder");
|
||||||
|
//// return new BCryptPasswordEncoder();
|
||||||
|
//// }
|
||||||
|
//}
|
||||||
|
|||||||
30
src/main/java/demo/api/config/JwtSecurityConfig.java
Normal file
30
src/main/java/demo/api/config/JwtSecurityConfig.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package demo.api.config;
|
||||||
|
|
||||||
|
import demo.api.jwt.JwtTokenFilter;
|
||||||
|
import demo.api.jwt.JwtTokenProvider;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SecurityConfigurerAdapter를 확장.
|
||||||
|
* JwtTokenProvider를 주입받음.
|
||||||
|
* JwtFilter를 통해 Security filterchain에 filter를 추가 등록
|
||||||
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class JwtSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
|
||||||
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
|
|
||||||
|
// public JwtSecurityConfig(JwtTokenProvider jwtTokenProvider) {
|
||||||
|
// this.jwtTokenProvider = jwtTokenProvider;
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(HttpSecurity http) throws Exception {
|
||||||
|
JwtTokenFilter customFilter = new JwtTokenFilter(jwtTokenProvider);
|
||||||
|
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
package demo.api.config;
|
package demo.api.config;
|
||||||
|
|
||||||
import demo.api.user.repository.UserRepository;
|
import demo.api.jwt.JwtAccessDeniedHandler;
|
||||||
|
import demo.api.jwt.JwtAuthenticationEntryPoint;
|
||||||
|
import demo.api.jwt.JwtTokenFilter;
|
||||||
|
import demo.api.jwt.JwtTokenProvider;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
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.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
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.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
@@ -17,16 +17,22 @@ import org.springframework.security.web.SecurityFilterChain;
|
|||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
@Bean
|
// 추가된 jwt 관련 친구들을 security config에 추가
|
||||||
public UserDetailsService userDetailsService() {
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
return new UserDetailsServiceImpl();
|
private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
|
||||||
}
|
private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
|
||||||
|
|
||||||
|
// @Bean
|
||||||
|
// public UserDetailsService userDetailsService() {
|
||||||
|
// return new UserDetailsServiceImpl();
|
||||||
|
// }
|
||||||
@Bean
|
@Bean
|
||||||
public BCryptPasswordEncoder passwordEncoder() {
|
public BCryptPasswordEncoder passwordEncoder() {
|
||||||
return new BCryptPasswordEncoder();
|
return new BCryptPasswordEncoder();
|
||||||
}
|
}
|
||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
|
//
|
||||||
http
|
http
|
||||||
.csrf().disable()
|
.csrf().disable()
|
||||||
.formLogin()
|
.formLogin()
|
||||||
@@ -36,11 +42,33 @@ public class SecurityConfig {
|
|||||||
.passwordParameter("password")
|
.passwordParameter("password")
|
||||||
.defaultSuccessUrl("/")
|
.defaultSuccessUrl("/")
|
||||||
.failureUrl("/user/signIn?fail=true");
|
.failureUrl("/user/signIn?fail=true");
|
||||||
|
|
||||||
|
//
|
||||||
http
|
http
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.antMatchers("/", "/user/signUp", "/user/userList", "/user/signIn*").permitAll()
|
.antMatchers(
|
||||||
|
"/",
|
||||||
|
"/user/signUp",
|
||||||
|
"/user/userList",
|
||||||
|
"/user/signIn*",
|
||||||
|
"/favicon.ico"
|
||||||
|
).permitAll()
|
||||||
.anyRequest().authenticated();
|
.anyRequest().authenticated();
|
||||||
|
|
||||||
|
// No session will be created or used by spring security
|
||||||
|
http
|
||||||
|
.sessionManagement()
|
||||||
|
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
||||||
|
|
||||||
|
// exception handling for jwt
|
||||||
|
http
|
||||||
|
.exceptionHandling()
|
||||||
|
.accessDeniedHandler(jwtAccessDeniedHandler)
|
||||||
|
.authenticationEntryPoint(jwtAuthenticationEntryPoint);
|
||||||
|
|
||||||
|
// Apply JWT
|
||||||
|
http.apply(new JwtSecurityConfig(jwtTokenProvider));
|
||||||
|
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Component
|
||||||
public class UserDetailsServiceImpl implements UserDetailsService {
|
public class UserDetailsServiceImpl implements UserDetailsService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package demo.api.jwt.exception;
|
package demo.api.exception;
|
||||||
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
24
src/main/java/demo/api/jwt/JwtAccessDeniedHandler.java
Normal file
24
src/main/java/demo/api/jwt/JwtAccessDeniedHandler.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package demo.api.jwt;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
|
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AccessDeniedHandler
|
||||||
|
*
|
||||||
|
* AuthenticationEntryPoint와 달리 AccessDeniedHandler는
|
||||||
|
* 유저 정보는 있으나, 엑세스 권한이 없는 경우 동작하는 친구이다.
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
|
||||||
|
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/main/java/demo/api/jwt/JwtAuthenticationEntryPoint.java
Normal file
34
src/main/java/demo/api/jwt/JwtAuthenticationEntryPoint.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package demo.api.jwt;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AuthenticationEntryPoint
|
||||||
|
*
|
||||||
|
* 인증 과정에서 실패하거나 인증을 위한 헤더정보를 보내지 않은 경우
|
||||||
|
* 401(UnAuthorized) 에러가 발생하게 된다.
|
||||||
|
*
|
||||||
|
* Spring Security에서 인증되지 않은 사용자에 대한 접근 처리는 AuthenticationEntryPoint가 담당하는데,
|
||||||
|
* commence 메소드가 실행되어 처리된다.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||||
|
@Override
|
||||||
|
public void commence(
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
AuthenticationException e
|
||||||
|
) throws IOException {
|
||||||
|
System.out.println(request.getRequestURI());
|
||||||
|
log.error("UnAuthorized -- message : " + e.getMessage()); // 로그를 남기고
|
||||||
|
response.sendRedirect("/user/signIn"); // 로그인 페이지로 리다이렉트되도록 하였다.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package demo.api.jwt;
|
package demo.api.jwt;
|
||||||
|
|
||||||
import demo.api.jwt.exception.CustomException;
|
import demo.api.exception.CustomException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
@@ -28,7 +28,7 @@ public class JwtTokenFilter extends OncePerRequestFilter {
|
|||||||
try {
|
try {
|
||||||
if (token != null && jwtTokenProvider.validateToken(token)) {
|
if (token != null && jwtTokenProvider.validateToken(token)) {
|
||||||
Authentication auth = jwtTokenProvider.getAuthentication(token);
|
Authentication auth = jwtTokenProvider.getAuthentication(token);
|
||||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
SecurityContextHolder.getContext().setAuthentication(auth); // 정상 토큰이면 SecurityContext에 저장
|
||||||
}
|
}
|
||||||
} catch (CustomException ex) {
|
} catch (CustomException ex) {
|
||||||
//this is very important, since it guarantees the user is not authenticated at all
|
//this is very important, since it guarantees the user is not authenticated at all
|
||||||
|
|||||||
@@ -1,31 +1,25 @@
|
|||||||
package demo.api.jwt;
|
package demo.api.jwt;
|
||||||
|
|
||||||
import demo.api.jwt.exception.CustomException;
|
import demo.api.exception.CustomException;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.ExpiredJwtException;
|
|
||||||
import io.jsonwebtoken.JwtException;
|
import io.jsonwebtoken.JwtException;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
import io.jsonwebtoken.MalformedJwtException;
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
|
|
||||||
// 유저 정보로 JWT 토큰을 만들거나 토큰을 바탕으로 유저 정보를 가져옴
|
// 유저 정보로 JWT 토큰을 만들거나 토큰을 바탕으로 유저 정보를 가져옴
|
||||||
@Component
|
@Component
|
||||||
public class JwtTokenProvider {
|
public class JwtTokenProvider {
|
||||||
/**
|
@Value("${jwt.token.secret-key}")
|
||||||
* THIS IS NOT A SECURE PRACTICE! For simplicity, we are storing a static key here. Ideally, in a
|
|
||||||
* microservices environment, this key would be kept on a config-server.
|
|
||||||
*/
|
|
||||||
@Value("${jwt.token.open-secret-key}")
|
|
||||||
private String secret_key;
|
private String secret_key;
|
||||||
|
|
||||||
@Value("${jwt.token.expire-length}")
|
@Value("${jwt.token.expire-length}")
|
||||||
@@ -34,36 +28,44 @@ public class JwtTokenProvider {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private UserDetailsService userDetailsService;
|
private UserDetailsService userDetailsService;
|
||||||
|
|
||||||
@PostConstruct // 의존성 주입이 이루어진 후 초기화를 수행
|
/**
|
||||||
protected void init() {
|
* 적절한 설정을 통해 토큰을 생성하여 반환
|
||||||
secret_key = Base64.getEncoder().encodeToString(secret_key.getBytes());
|
* @param authentication
|
||||||
}
|
* @return
|
||||||
|
*/
|
||||||
|
public String generateToken(Authentication authentication) {
|
||||||
|
|
||||||
public String createToken(String username, List<AppUserRole> appUserRoles) {
|
Claims claims = Jwts.claims().setSubject(authentication.getName());
|
||||||
|
// claims.put("auth", appUserRoles.stream().map(s -> new SimpleGrantedAuthority(s.getAuthority())).filter(Objects::nonNull).collect(Collectors.toList()));
|
||||||
Claims claims = Jwts.claims().setSubject(username);
|
|
||||||
claims.put("auth", appUserRoles.stream().map(s -> new SimpleGrantedAuthority(s.getAuthority())).filter(Objects::nonNull).collect(Collectors.toList()));
|
|
||||||
|
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date validity = new Date(now.getTime() + expire_time);
|
Date expiresIn = new Date(now.getTime() + expire_time);
|
||||||
|
|
||||||
return Jwts.builder()
|
return Jwts.builder()
|
||||||
.setClaims(claims)
|
.setClaims(claims)
|
||||||
.setIssuedAt(now)
|
.setIssuedAt(now)
|
||||||
.setExpiration(validity)
|
.setExpiration(expiresIn)
|
||||||
.signWith(SignatureAlgorithm.HS256, secret_key)
|
.signWith(SignatureAlgorithm.HS256, secret_key)
|
||||||
.compact();
|
.compact();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 토큰으로부터 클레임을 만들고, 이를 통해 User 객체를 생성하여 Authentication 객체를 반환
|
||||||
|
* @param token
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Authentication getAuthentication(String token) {
|
public Authentication getAuthentication(String token) {
|
||||||
UserDetails userDetails = userDetailsService.loadUserByUsername(getUsername(token));
|
String username = Jwts.parser().setSigningKey(secret_key).parseClaimsJws(token).getBody().getSubject();
|
||||||
|
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||||
|
|
||||||
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
|
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername(String token) {
|
/**
|
||||||
return Jwts.parser().setSigningKey(secret_key).parseClaimsJws(token).getBody().getSubject();
|
* http 헤더로부터 bearer 토큰을 가져옴.
|
||||||
}
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public String resolveToken(HttpServletRequest req) {
|
public String resolveToken(HttpServletRequest req) {
|
||||||
String bearerToken = req.getHeader("Authorization");
|
String bearerToken = req.getHeader("Authorization");
|
||||||
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
|
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
|
||||||
@@ -72,6 +74,11 @@ public class JwtTokenProvider {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 토큰을 검증
|
||||||
|
* @param token
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public boolean validateToken(String token) {
|
public boolean validateToken(String token) {
|
||||||
try {
|
try {
|
||||||
Jwts.parser().setSigningKey(secret_key).parseClaimsJws(token);
|
Jwts.parser().setSigningKey(secret_key).parseClaimsJws(token);
|
||||||
|
|||||||
@@ -42,14 +42,9 @@ public class UserController {
|
|||||||
|
|
||||||
return "user/signIn";
|
return "user/signIn";
|
||||||
}
|
}
|
||||||
// @Autowired
|
|
||||||
// private UserDetailsService userDetailsService;
|
|
||||||
@GetMapping("/profile")
|
@GetMapping("/profile")
|
||||||
public String profile(Model model, @AuthenticationPrincipal UserDetails userDetails) {
|
public String profile(Model model, @AuthenticationPrincipal UserDetails userDetails) {
|
||||||
// Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
|
||||||
// System.out.println("principal : " + authentication.getPrincipal());
|
|
||||||
// System.out.println("Implementing class of UserDetails: " + authentication.getPrincipal().getClass());
|
|
||||||
// System.out.println("Implementing class of UserDetailsService: " + userDetailsService.getClass());
|
|
||||||
if (userDetails != null) {
|
if (userDetails != null) {
|
||||||
User userDetail = userService.findByEmail(userDetails.getUsername())
|
User userDetail = userService.findByEmail(userDetails.getUsername())
|
||||||
.orElseThrow(() -> new UserNotFoundException());
|
.orElseThrow(() -> new UserNotFoundException());
|
||||||
@@ -60,10 +55,9 @@ public class UserController {
|
|||||||
return "user/profile";
|
return "user/profile";
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/user/userList")
|
@GetMapping("/userList")
|
||||||
public String showUserList(Model model) {
|
public String showUserList(Model model) {
|
||||||
List<User> userList = userService.findAll();
|
List<User> userList = userService.findAll();
|
||||||
|
|
||||||
model.addAttribute("userList", userList);
|
model.addAttribute("userList", userList);
|
||||||
|
|
||||||
return "user/userList";
|
return "user/userList";
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ spring:
|
|||||||
jpa:
|
jpa:
|
||||||
show-sql: true
|
show-sql: true
|
||||||
hibernate:
|
hibernate:
|
||||||
|
format_sql: true
|
||||||
ddl-auto: none
|
ddl-auto: none
|
||||||
jwt:
|
jwt:
|
||||||
token:
|
token:
|
||||||
secret-key: open-secret-key
|
secret-key: aG91Mjctc2ltcGxlLXNwcmluZy1ib290LWFwaS1qd3QK
|
||||||
expire-length: 300000
|
expire-length: 300000
|
||||||
Reference in New Issue
Block a user