diff --git a/build.gradle b/build.gradle index c40ed21..6d53761 100644 --- a/build.gradle +++ b/build.gradle @@ -51,6 +51,7 @@ dependencies { // database implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'mysql:mysql-connector-java' + implementation 'org.springframework.boot:spring-boot-starter-data-redis' // test testImplementation 'org.springframework.boot:spring-boot-starter-test' @@ -58,6 +59,11 @@ dependencies { // infra implementation 'org.springframework.boot:spring-boot-starter-security' + + // jwt + implementation "io.jsonwebtoken:jjwt-api:${jsonwebtokenVersion}" + implementation "io.jsonwebtoken:jjwt-impl:${jsonwebtokenVersion}" + implementation "io.jsonwebtoken:jjwt-jackson:${jsonwebtokenVersion}" } test { diff --git a/resources/local-develop-environment/docker-compose.yml b/resources/local-develop-environment/docker-compose.yml index 5f1b5ce..806adfc 100644 --- a/resources/local-develop-environment/docker-compose.yml +++ b/resources/local-develop-environment/docker-compose.yml @@ -21,4 +21,10 @@ services: environment: - ADMINER_DEFAULT_SERVER=golajuma-mysql8 - ADMINER_DESIGN=nette - - ADMINER_PLUGINS=tables-filter tinymce \ No newline at end of file + - ADMINER_PLUGINS=tables-filter tinymce + + redis-docker: + container_name: golajuma-redis + image: redis:latest + ports: + - "16379:6379" diff --git a/src/main/java/com/kakao/golajuma/auth/domain/exception/NotFoundException.java b/src/main/java/com/kakao/golajuma/auth/domain/exception/NotFoundException.java new file mode 100644 index 0000000..a6c47ad --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/domain/exception/NotFoundException.java @@ -0,0 +1,11 @@ +package com.kakao.golajuma.auth.domain.exception; + +import com.kakao.golajuma.common.exception.BusinessException; +import org.springframework.http.HttpStatus; + +public class NotFoundException extends BusinessException { + + public NotFoundException(String message) { + super(message, HttpStatus.NOT_FOUND); + } +} diff --git a/src/main/java/com/kakao/golajuma/auth/domain/exception/NotValidToken.java b/src/main/java/com/kakao/golajuma/auth/domain/exception/NotValidToken.java new file mode 100644 index 0000000..a7c5103 --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/domain/exception/NotValidToken.java @@ -0,0 +1,11 @@ +package com.kakao.golajuma.auth.domain.exception; + +import com.kakao.golajuma.common.exception.BusinessException; +import org.springframework.http.HttpStatus; + +public class NotValidToken extends BusinessException { + + public NotValidToken(String message) { + super(message, HttpStatus.BAD_REQUEST); + } +} diff --git a/src/main/java/com/kakao/golajuma/auth/domain/model/RefreshToken.java b/src/main/java/com/kakao/golajuma/auth/domain/model/RefreshToken.java new file mode 100644 index 0000000..0e829bb --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/domain/model/RefreshToken.java @@ -0,0 +1,17 @@ +package com.kakao.golajuma.auth.domain.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Getter +@ToString +@AllArgsConstructor +@NoArgsConstructor +@Builder(toBuilder = true) +public class RefreshToken { + private String refreshToken; + private Long userId; +} diff --git a/src/main/java/com/kakao/golajuma/auth/domain/service/LoginUserService.java b/src/main/java/com/kakao/golajuma/auth/domain/service/LoginUserService.java new file mode 100644 index 0000000..30822c6 --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/domain/service/LoginUserService.java @@ -0,0 +1,55 @@ +package com.kakao.golajuma.auth.domain.service; + +import com.kakao.golajuma.auth.domain.exception.NotFoundException; +import com.kakao.golajuma.auth.domain.token.TokenProvider; +import com.kakao.golajuma.auth.domain.token.TokenResolver; +import com.kakao.golajuma.auth.infra.entity.UserEntity; +import com.kakao.golajuma.auth.infra.repository.UserRepository; +import com.kakao.golajuma.auth.web.dto.converter.TokenConverter; +import com.kakao.golajuma.auth.web.dto.request.LoginUserRequest; +import com.kakao.golajuma.auth.web.dto.response.TokenResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class LoginUserService { + + private final TokenProvider tokenProvider; + private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; + private final TokenConverter tokenConverter; + private final TokenResolver tokenResolver; + private final TokenService tokenService; + + @Transactional + public TokenResponse execute(final LoginUserRequest request) { + UserEntity userEntity = + userRepository + .findByEmail(request.getEmail()) + .orElseThrow(() -> new NotFoundException("존재하지 않는 이메일입니다.")); + + validPassword(request.getPassword(), userEntity); + + String accessToken = tokenProvider.createAccessToken(userEntity.getId()); + String refreshToken = tokenProvider.createRefreshToken(userEntity.getId()); + + tokenService.execute(userEntity.getId(), refreshToken); + + return tokenConverter.from( + accessToken, tokenResolver.getExpiredDate(accessToken), refreshToken); + } + + private void validPassword(final String requestPassword, final UserEntity userEntity) { + if (!matchPassword(requestPassword, userEntity.getPassword())) { + throw new NotFoundException("존재하지 않는 비밀번호입니다"); + } + } + + private boolean matchPassword(final String requestPassword, final String password) { + return passwordEncoder.matches(requestPassword, password); + } +} diff --git a/src/main/java/com/kakao/golajuma/auth/domain/service/TokenService.java b/src/main/java/com/kakao/golajuma/auth/domain/service/TokenService.java new file mode 100644 index 0000000..fc9b463 --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/domain/service/TokenService.java @@ -0,0 +1,19 @@ +package com.kakao.golajuma.auth.domain.service; + +import com.kakao.golajuma.auth.domain.model.RefreshToken; +import com.kakao.golajuma.auth.infra.repository.RefreshTokenRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class TokenService { + private final RefreshTokenRepository refreshTokenRepository; + + @Transactional + public void execute(Long userId, String token) { + RefreshToken refreshToken = RefreshToken.builder().refreshToken(token).userId(userId).build(); + refreshTokenRepository.save(refreshToken); + } +} diff --git a/src/main/java/com/kakao/golajuma/auth/domain/token/TokenProvider.java b/src/main/java/com/kakao/golajuma/auth/domain/token/TokenProvider.java new file mode 100644 index 0000000..905de54 --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/domain/token/TokenProvider.java @@ -0,0 +1,54 @@ +package com.kakao.golajuma.auth.domain.token; + +import io.jsonwebtoken.Header; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import javax.crypto.SecretKey; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class TokenProvider { + + private static final String USER_ID_CLAIM_KEY = "memberId"; + private static final String USER_ROLE_CLAIM_KEY = "memberRole"; + private final SecretKey accessSecretKey; + + private final long accessValidTime; + private final SecretKey refreshSecretKey; + + private final long refreshValidTime; + + public TokenProvider( + @Value("${security.jwt.token.access.secretKey}") String accessSecretKey, + @Value("${security.jwt.token.access.validTime}") long accessValidTime, + @Value("${security.jwt.token.refresh.secretKey}") String refreshSecretKey, + @Value("${security.jwt.token.refresh.validTime}") long refreshValidTime) { + this.accessSecretKey = Keys.hmacShaKeyFor(accessSecretKey.getBytes(StandardCharsets.UTF_8)); + this.accessValidTime = accessValidTime; + this.refreshSecretKey = Keys.hmacShaKeyFor(refreshSecretKey.getBytes(StandardCharsets.UTF_8)); + this.refreshValidTime = refreshValidTime; + } + + private String createToken(final Long userId, final SecretKey secretKey, final long validTime) { + final Date now = new Date(); + + return Jwts.builder() + .setHeaderParam(Header.TYPE, Header.JWT_TYPE) + .claim(USER_ID_CLAIM_KEY, userId) + .setIssuedAt(now) + .setExpiration(new Date(now.getTime() + validTime)) + .signWith(secretKey) + .compact(); + } + + public String createAccessToken(final Long userId) { + return createToken(userId, accessSecretKey, accessValidTime); + } + + public String createRefreshToken(final Long userId) { + return createToken(userId, refreshSecretKey, refreshValidTime); + } +} diff --git a/src/main/java/com/kakao/golajuma/auth/domain/token/TokenResolver.java b/src/main/java/com/kakao/golajuma/auth/domain/token/TokenResolver.java new file mode 100644 index 0000000..f30c278 --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/domain/token/TokenResolver.java @@ -0,0 +1,43 @@ +package com.kakao.golajuma.auth.domain.token; + +import com.kakao.golajuma.auth.domain.exception.NotValidToken; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import javax.crypto.SecretKey; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class TokenResolver { + + private static final String USER_ID_CLAIM_KEY = "memberId"; + private static final String USER_ROLE_CLAIM_KEY = "memberRole"; + private final SecretKey accessSecretKey; + private final SecretKey refreshSecretKey; + + public TokenResolver( + @Value("${security.jwt.token.access.secretKey}") String accessSecretKey, + @Value("${security.jwt.token.refresh.secretKey}") String refreshSecretKey) { + this.accessSecretKey = Keys.hmacShaKeyFor(accessSecretKey.getBytes(StandardCharsets.UTF_8)); + this.refreshSecretKey = Keys.hmacShaKeyFor(refreshSecretKey.getBytes(StandardCharsets.UTF_8)); + } + + private Claims getClaims(final String token) { + try { + return Jwts.parserBuilder() + .setSigningKey(accessSecretKey) + .build() + .parseClaimsJws(token) + .getBody(); + } catch (Exception e) { + throw new NotValidToken("유효하지 않은 토큰입니다."); + } + } + + public Date getExpiredDate(final String token) { + return getClaims(token).getExpiration(); + } +} diff --git a/src/main/java/com/kakao/golajuma/auth/infra/repository/RefreshTokenRepository.java b/src/main/java/com/kakao/golajuma/auth/infra/repository/RefreshTokenRepository.java new file mode 100644 index 0000000..f4bda1d --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/infra/repository/RefreshTokenRepository.java @@ -0,0 +1,42 @@ +package com.kakao.golajuma.auth.infra.repository; + +import com.kakao.golajuma.auth.domain.model.RefreshToken; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Repository; + +@Repository +@Slf4j +public class RefreshTokenRepository { + + private RedisTemplate redisTemplate; + + @Value("${redis.timeToLive}") + private long ttl; + + public RefreshTokenRepository(final RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + public void save(final RefreshToken refreshToken) { + ValueOperations valueOperations = redisTemplate.opsForValue(); + valueOperations.set(refreshToken.getUserId(), refreshToken.getRefreshToken()); + redisTemplate.expire(refreshToken.getUserId(), ttl, TimeUnit.SECONDS); + } + + public Optional findById(final Long userId) { + ValueOperations valueOperations = redisTemplate.opsForValue(); + String refreshToken = valueOperations.get(userId); + + if (Objects.isNull(refreshToken)) { + return Optional.empty(); + } + + return Optional.of(new RefreshToken(refreshToken, userId)); + } +} diff --git a/src/main/java/com/kakao/golajuma/auth/infra/repository/UserRepository.java b/src/main/java/com/kakao/golajuma/auth/infra/repository/UserRepository.java index 41102ab..354fae5 100644 --- a/src/main/java/com/kakao/golajuma/auth/infra/repository/UserRepository.java +++ b/src/main/java/com/kakao/golajuma/auth/infra/repository/UserRepository.java @@ -1,10 +1,13 @@ package com.kakao.golajuma.auth.infra.repository; import com.kakao.golajuma.auth.infra.entity.UserEntity; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface UserRepository extends JpaRepository { boolean existsByEmail(String email); boolean existsByNickname(String nickname); + + Optional findByEmail(String email); } diff --git a/src/main/java/com/kakao/golajuma/auth/web/controller/LoginController.java b/src/main/java/com/kakao/golajuma/auth/web/controller/LoginController.java new file mode 100644 index 0000000..3e4c500 --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/web/controller/LoginController.java @@ -0,0 +1,45 @@ +package com.kakao.golajuma.auth.web.controller; + +import com.kakao.golajuma.auth.domain.service.LoginUserService; +import com.kakao.golajuma.auth.web.dto.request.LoginUserRequest; +import com.kakao.golajuma.auth.web.dto.response.TokenResponse; +import com.kakao.golajuma.common.support.respnose.ApiResponse; +import com.kakao.golajuma.common.support.respnose.ApiResponseBody.SuccessBody; +import com.kakao.golajuma.common.support.respnose.ApiResponseGenerator; +import com.kakao.golajuma.common.support.respnose.MessageCode; +import javax.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseCookie; +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; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/auth") +public class LoginController { + private static final String REFRESH_TOKEN = "refreshToken"; + private static final int REFRESH_TOKEN_EXPIRATION = 7 * 24 * 60 * 60; + private final LoginUserService loginUserUseCase; + + @PostMapping("/login") + public ApiResponse> signIn( + @RequestBody @Valid LoginUserRequest request) { + final TokenResponse tokenResponse = loginUserUseCase.execute(request); + final ResponseCookie cookie = putTokenInCookie(tokenResponse); + return ApiResponseGenerator.success( + tokenResponse, HttpStatus.OK, MessageCode.CREATE, cookie.toString()); + } + + private ResponseCookie putTokenInCookie(final TokenResponse tokenResponse) { + return ResponseCookie.from(REFRESH_TOKEN, tokenResponse.getRefreshToken()) + .maxAge(REFRESH_TOKEN_EXPIRATION) + .path("/") + .sameSite("None") + .secure(true) + .httpOnly(true) + .build(); + } +} diff --git a/src/main/java/com/kakao/golajuma/auth/web/dto/converter/TokenConverter.java b/src/main/java/com/kakao/golajuma/auth/web/dto/converter/TokenConverter.java new file mode 100644 index 0000000..e5a3fc0 --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/web/dto/converter/TokenConverter.java @@ -0,0 +1,19 @@ +package com.kakao.golajuma.auth.web.dto.converter; + +import com.kakao.golajuma.auth.web.dto.response.TokenResponse; +import java.util.Date; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class TokenConverter { + + public TokenResponse from(String accessToken, Date expiredTime, String refreshToken) { + return TokenResponse.builder() + .accessToken(accessToken) + .expiredTime(expiredTime) + .refreshToken(refreshToken) + .build(); + } +} diff --git a/src/main/java/com/kakao/golajuma/auth/web/dto/request/LoginUserRequest.java b/src/main/java/com/kakao/golajuma/auth/web/dto/request/LoginUserRequest.java new file mode 100644 index 0000000..1a8231d --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/web/dto/request/LoginUserRequest.java @@ -0,0 +1,24 @@ +package com.kakao.golajuma.auth.web.dto.request; + +import com.kakao.golajuma.auth.web.supplier.EmailSupplier; +import com.kakao.golajuma.common.marker.AbstractRequestDto; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Builder(toBuilder = true) +public class LoginUserRequest implements AbstractRequestDto, EmailSupplier { + + @NotNull @Email private String email; + + @NotNull + @Size(min = 8) + private String password; +} diff --git a/src/main/java/com/kakao/golajuma/auth/web/dto/response/TokenResponse.java b/src/main/java/com/kakao/golajuma/auth/web/dto/response/TokenResponse.java new file mode 100644 index 0000000..60d631b --- /dev/null +++ b/src/main/java/com/kakao/golajuma/auth/web/dto/response/TokenResponse.java @@ -0,0 +1,20 @@ +package com.kakao.golajuma.auth.web.dto.response; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.kakao.golajuma.common.marker.AbstractResponseDto; +import java.util.Date; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Builder(toBuilder = true) +public class TokenResponse implements AbstractResponseDto { + + private String accessToken; + private Date expiredTime; + @JsonIgnore private String refreshToken; +} diff --git a/src/main/java/com/kakao/golajuma/common/support/respnose/ApiResponse.java b/src/main/java/com/kakao/golajuma/common/support/respnose/ApiResponse.java index fe4710d..3912bc9 100644 --- a/src/main/java/com/kakao/golajuma/common/support/respnose/ApiResponse.java +++ b/src/main/java/com/kakao/golajuma/common/support/respnose/ApiResponse.java @@ -3,6 +3,7 @@ import lombok.Getter; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.util.MultiValueMap; @Getter public class ApiResponse extends ResponseEntity { @@ -14,4 +15,8 @@ public ApiResponse(final HttpStatus status) { public ApiResponse(final B body, final HttpStatus status) { super(body, status); } + + public ApiResponse(final B body, MultiValueMap headers, HttpStatus status) { + super(body, headers, status); + } } diff --git a/src/main/java/com/kakao/golajuma/common/support/respnose/ApiResponseGenerator.java b/src/main/java/com/kakao/golajuma/common/support/respnose/ApiResponseGenerator.java index ee5d454..000224e 100644 --- a/src/main/java/com/kakao/golajuma/common/support/respnose/ApiResponseGenerator.java +++ b/src/main/java/com/kakao/golajuma/common/support/respnose/ApiResponseGenerator.java @@ -3,6 +3,8 @@ import lombok.experimental.UtilityClass; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; @UtilityClass public class ApiResponseGenerator { @@ -18,6 +20,14 @@ public static ApiResponse> success( new ApiResponseBody.SuccessBody<>(data, code.getMessage(), code.getCode()), status); } + public static ApiResponse> success( + final D data, final HttpStatus status, MessageCode code, String cookieValue) { + return new ApiResponse<>( + new ApiResponseBody.SuccessBody<>(data, code.getMessage(), code.getCode()), + setCookie(cookieValue), + status); + } + public static ApiResponse>> success( final Page data, final HttpStatus status, final MessageCode code) { return new ApiResponse<>( @@ -41,4 +51,11 @@ public static ApiResponse fail( final String code, final String message, final HttpStatus status) { return new ApiResponse<>(new ApiResponseBody.FailureBody(code, message), status); } + + private MultiValueMap setCookie(String cookieValue) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("Set-Cookie", cookieValue); + + return map; + } } diff --git a/src/main/java/com/kakao/golajuma/config/RedisConfig.java b/src/main/java/com/kakao/golajuma/config/RedisConfig.java new file mode 100644 index 0000000..6e144d1 --- /dev/null +++ b/src/main/java/com/kakao/golajuma/config/RedisConfig.java @@ -0,0 +1,45 @@ +package com.kakao.golajuma.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisConfig { + + private final String host; + private final int port; + + public RedisConfig( + @Value("${spring.redis.host}") final String host, + @Value("${spring.redis.port}") final int port) { + this.host = host; + this.port = port; + } + + @Bean + public RedisConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(host, port); + } + + @Bean + public RedisTemplate redisTemplate() { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory()); + + redisTemplate.setKeySerializer(new GenericJackson2JsonRedisSerializer()); + redisTemplate.setValueSerializer(new StringRedisSerializer()); + + redisTemplate.setHashKeySerializer(new GenericJackson2JsonRedisSerializer()); + redisTemplate.setHashValueSerializer(new StringRedisSerializer()); + + redisTemplate.setDefaultSerializer(new StringRedisSerializer()); + + return redisTemplate; + } +} diff --git a/src/main/java/com/kakao/golajuma/config/SecurityConfig.java b/src/main/java/com/kakao/golajuma/config/SecurityConfig.java new file mode 100644 index 0000000..8a24b94 --- /dev/null +++ b/src/main/java/com/kakao/golajuma/config/SecurityConfig.java @@ -0,0 +1,43 @@ +package com.kakao.golajuma.config; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +@RequiredArgsConstructor +@EnableWebSecurity +public class SecurityConfig { + private final AuthenticationConfiguration authenticationConfiguration; + + @Bean + public PasswordEncoder passwordEncoder() { + return PasswordEncoderFactories.createDelegatingPasswordEncoder(); + } + + @Bean + public AuthenticationManager authenticationManager() throws Exception { + return authenticationConfiguration.getAuthenticationManager(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.csrf().disable(); + http.formLogin().disable(); + http.httpBasic().disable(); + http.cors(); + http.authorizeRequests().antMatchers(HttpMethod.POST, "/users/auth/**").permitAll(); + + http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + return http.build(); + } +} diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local-mysql.yml similarity index 92% rename from src/main/resources/application-local.yml rename to src/main/resources/application-local-mysql.yml index 10ffada..200f829 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local-mysql.yml @@ -1,7 +1,7 @@ spring: config: activate: - on-profile: local + on-profile: local-mysql datasource: url: jdbc:mysql://localhost:13306/golajuma?allowPublicKeyRetrieval=true&rewriteBatchedStatements=true username: root diff --git a/src/main/resources/application-local-redis.yml b/src/main/resources/application-local-redis.yml new file mode 100644 index 0000000..36a3021 --- /dev/null +++ b/src/main/resources/application-local-redis.yml @@ -0,0 +1,7 @@ +spring: + redis: + host: localhost + port: 16379 + +redis: + timeToLive : 60 \ No newline at end of file diff --git a/src/main/resources/application-local-security.yml b/src/main/resources/application-local-security.yml new file mode 100644 index 0000000..25a2d14 --- /dev/null +++ b/src/main/resources/application-local-security.yml @@ -0,0 +1,9 @@ +security: + jwt: + token: + access: + secretKey: asccesssecretkeygolajumasecrekey + validTime: 1800000 + refresh: + secretKey: refreshsecretkeygolajumasecrekey + validTime: 604800000 \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 7455971..cc51800 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,3 +1,8 @@ spring: profiles: - default: local + group: + local: + - local-mysql + - local-security + - local-redis + active: local