Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[27] keycloak + oauth 2.0 적용 및 회원 가입 수정 #31

Merged
merged 54 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
f3be8be
[20] 상품 정보 수정 API
ohsuha Sep 1, 2024
095e967
[20] 상품 삭제
ohsuha Sep 1, 2024
f772d4c
[16] swagger 추가
ohsuha Sep 1, 2024
bf22498
[23] address 테이블 수정
ohsuha Sep 1, 2024
f85c2ea
[23] db 테이블 drop 문 추가
ohsuha Sep 1, 2024
754a2f7
[23] add address
ohsuha Sep 1, 2024
a2df6d1
[23] @Transactional 추가
ohsuha Sep 1, 2024
27c8427
[16] swagger 추가
ohsuha Sep 1, 2024
f212dde
[10] yml 설정 하나로 통일
ohsuha Sep 1, 2024
366259e
[20] 코드 리뷰 반영
ohsuha Sep 1, 2024
e5dbf2e
[10] yml 설정 하나로 통일
ohsuha Sep 1, 2024
d328ab5
[20] 코드 리뷰 반영
ohsuha Sep 1, 2024
235102f
Merge branch 'feature/20-product-modify-delete' into feature/23-add-a…
ohsuha Sep 1, 2024
b8d105e
[20] @Transactional 어노테이션 추가
ohsuha Sep 1, 2024
f5b8eff
Merge pull request #24 from f-lab-edu/feature/23-add-address
ohsuha Sep 1, 2024
5046642
Merge branch 'feature/16-swagger' into feature/20-product-modify-delete
ohsuha Sep 1, 2024
090fca1
[16] server-url 추가
ohsuha Sep 2, 2024
06ad7f7
[20] 코드 리뷰 반영
ohsuha Sep 1, 2024
f6423ca
[20] 불필요한 코드 삭제
Sep 3, 2024
cbd79bc
[25] 주소 수정, 삭제, 리스트
ohsuha Sep 3, 2024
05c9351
[21] product 단건 조회
ohsuha Sep 3, 2024
a2109d3
[25] 코드리뷰 반영
ohsuha Sep 9, 2024
aeba881
[25] flyaway 적용
ohsuha Sep 9, 2024
e2b89db
[20] updatePrimary 를 매개변수 받도록 수정
ohsuha Sep 9, 2024
5a046d6
[20] transactional 어노테이션 추가
ohsuha Sep 9, 2024
715d3c5
Merge branch 'develop' into feature/20-product-modify-delete
ohsuha Sep 9, 2024
bbe87ed
[25] flyaway 적용
ohsuha Sep 9, 2024
f84161f
[20] updatePrimary 를 매개변수 받도록 수정
ohsuha Sep 9, 2024
557276f
[20] transactional 어노테이션 추가
ohsuha Sep 9, 2024
311b514
[25] 주소 수정, 삭제, 리스트
ohsuha Sep 3, 2024
b76602e
[25] 코드리뷰 반영
ohsuha Sep 9, 2024
843c825
[21] product 생성시 isDeleted false 로 추가
ohsuha Sep 9, 2024
83c5304
[21] product list
ohsuha Sep 9, 2024
2c1e546
Merge pull request #28 from f-lab-edu/feature/product/21-product-list
ohsuha Sep 11, 2024
95e79b7
Merge branch 'feature/20-product-modify-delete' into feature/user/25-…
ohsuha Sep 11, 2024
cfaee49
[25] 주소 업데이트 기능 삭제
ohsuha Sep 12, 2024
93967ce
[11] 장바구니에 상품 추가
ohsuha Sep 12, 2024
7791a0e
[11] 장바구니 내용물 삭제
ohsuha Sep 12, 2024
3eb927e
[11] 장바구니에 담은 물건 수량 수정
ohsuha Sep 12, 2024
5db9901
code formatter
ohsuha Sep 12, 2024
bce1590
[11] 장바구니에서 상품 삭제시 다건 삭제 하도록 수정
ohsuha Sep 12, 2024
bd02af3
[11] cart list
ohsuha Sep 12, 2024
eb80d6d
[12] 상품 주문
ohsuha Sep 12, 2024
cd554bd
[12] order detail 을 batchUpdate 를 통해 bulk insert
ohsuha Sep 13, 2024
aea5d94
[12] 배송지 입력도 batchUpdate 를 사용하도록 수정
ohsuha Sep 13, 2024
8ac7cd0
[12] cart 의 userid, product id 를 unique 로 설정 후 인덱스 설정
ohsuha Sep 14, 2024
503dc1a
[27] keyclock 을 인가 서버로
ohsuha Sep 15, 2024
a3faf06
[27] keyclock clinet 통한 회원 가입
ohsuha Sep 15, 2024
018ba66
[27] 키클락을 통한 유저 생성 및 DB 정보 저장
ohsuha Sep 15, 2024
f99f9cf
[27] 보상 트랜잭션을 통한 유저 등록 실패 처리
ohsuha Sep 19, 2024
753602b
[27] 카카오 계정으로 회원가입 및 로그인
ohsuha Sep 21, 2024
9de69af
[27] 코드리뷰 수정
ohsuha Sep 25, 2024
3b0b63b
[27] entity 생성시 dto 에서 값을 가져오도록 수정
ohsuha Sep 27, 2024
8e9eb4b
[27] webhook api에 api key 설정
ohsuha Sep 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ dependencies {
implementation 'org.flywaydb:flyway-mysql'
implementation 'org.flywaydb:flyway-core'

// oauth 2.0
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'

// keycloak
implementation 'org.keycloak:keycloak-admin-client:25.0.5'

// test dependency
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.example.commerce_site.application.auth;

import org.example.commerce_site.application.auth.dto.OAuthAccessTokenResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class KeycloakAuthService {
private final RestTemplate restTemplate = new RestTemplate();
@Value("${oauth.keycloak.grant-type}")
private String GRANT_TYPE;
@Value("${oauth.keycloak.credentials.client}")
private String CLIENT_ID;
@Value("${oauth.keycloak.credentials.secret}")
private String CLIENT_SECRET;
@Value("${oauth.keycloak.uri.redirect}")
private String REDIRECT_URI;
@Value("${oauth.keycloak.uri.token}")
private String TOKEN_URI;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Value를 활용해서 각각의 필드를 받았는데, 이걸 좀 더 쉽게 한 번에 받는 방법은 없을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KeycloakProperties 클래스를 만들어 value 로 가져올 수 있는 것들을 @ConfigurationProperties(prefix = "oauth.keycloak") 어노테이션 사용해 이쪽에서 가져오도록 설정했습니다!


public OAuthAccessTokenResponse.Keycloak getAccessToken(String code) {
MultiValueMap<String, String> info = new LinkedMultiValueMap<>();
info.add("grant_type", GRANT_TYPE);
info.add("client_id", CLIENT_ID);
info.add("client_secret", CLIENT_SECRET);
info.add("redirect_uri", REDIRECT_URI);
info.add("code", code);

final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

final HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(info, headers);

return restTemplate.postForEntity(TOKEN_URI, httpEntity, OAuthAccessTokenResponse.Keycloak.class).getBody();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http 요청을 하기위해서 map을 활용했는데, dto로 클래스를 만드는 것과 map을 사용하는 것에는 어떤 차이가 있을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DTO로 만들면 타입 안정성들을 체크할 수 있을것같습니다.
DTO를 직접 HttpEntity에 넣으면, REST API 호출 시 DTO의 필드가 JSON 형태로 변환됩니다. 하지만 application/x-www-form-urlencoded 형식으로 전송하려면 각 필드가 URL 인코딩 된 형태로 전달되어야 하므로, DTO의 필드를 그 형식에 맞게 변환해야 합니다.

맵을 사용하면 RestTemplate의 postForEntity 메서드는 MultiValueMap 형식의 요청 본문을 자동으로 URL 인코딩하여 전송합니다.

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.example.commerce_site.application.auth.dto;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

public class OAuthAccessTokenResponse {
@Getter
@Setter
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Keycloak {
@JsonProperty("access_token")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

snake_case를 지원하기 위해 모든 필드에 @JsonProperty를 활용했는데, 다른 방법은 없을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존에 이미 yml 에 sping.jackson.property-naming-strategy: SNAKE_CASE 를 지정했는데 키클락에서 보내는 요청에 대해서는 어째선지 설정이 제대로 되지 않는것같아서 해당 repsonse 클래스에@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) 를 설정하는 방식으로 수정했습니다!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

키클락에 보내는 요청에 대해서는 왜 설정이 제대로 되지 않는걸까요?

private String accessToken;

@JsonProperty("expires_in")
private int expiresIn;

@JsonProperty("refresh_expires_in")
private int refreshExpiresIn;

@JsonProperty("refresh_token")
private String refreshToken;

@JsonProperty("token_type")
private String tokenType;

@JsonProperty("id_token")
private String idToken;

@JsonProperty("not-before-policy")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것만 kebab-case인데 맞나요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!

private int notBeforePolicy;

@JsonProperty("session_state")
private String sessionState;

@JsonProperty("scope")
private String scope;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.example.commerce_site.application.user;

import org.example.commerce_site.application.user.dto.UserRequestDto;
import org.example.commerce_site.application.user.dto.UserResponseDto;
import org.example.commerce_site.common.exception.CustomException;
import org.example.commerce_site.common.exception.ErrorCode;
import org.example.commerce_site.domain.User;
Expand All @@ -17,17 +16,16 @@
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;

@Transactional
public UserResponseDto.Create create(UserRequestDto.Create dto) {
// TODO : email 중복 체크
return UserResponseDto.Create.of(userRepository.save(UserRequestDto.Create.toEntity(dto)));
}


@Transactional(readOnly = true)
public User getUser(Long userId) {
return userRepository.findById(userId).orElseThrow(
() -> new CustomException(ErrorCode.USER_NOT_FOUND)
);
}

@Transactional
public void create(UserRequestDto.Create dto) {
userRepository.save(UserRequestDto.Create.toEntity(dto, dto.getId()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ public class UserRequestDto {
@Builder
@ToString
public static class Create {
private String id;
private String name;
private String email;
private String password;

public static User toEntity(UserRequestDto.Create dto) {
public static User toEntity(UserRequestDto.Create dto, String authId) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사용하는 곳을 보니 dto.getId()를 하는데 따로 받는 이유가 있나요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추후 사용자 탈퇴 처리 등을 할때 키클락에 등록된 아이디로 유저를 찾아 삭제하기 위해 저장해뒀습니다

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 제 얘기는 이 함수를 호출하는 곳에서,

UserRequestDto.Create.toEntity(dto, dto.getId())

위와 같은 형태로 처리를 하고 있는데, UserRequestDto.Create만 받는게 아니라, authId를 따로 받는 이유가 궁금해서 남긴 리뷰였습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 dto.getId() 를 하면 되는 것인데 실수했습니다;

return User.builder()
.authId(authId)
.name(dto.getName())
.email(dto.getEmail())
.password(dto.getPassword())
.status(UserStatus.ACTIVE)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public enum ErrorCode {

//user
USER_NOT_FOUND(HttpStatus.NOT_FOUND, 404, "회원 정보를 찾을 수 없습니다."),
EMAIL_ALREADY_EXISTED(HttpStatus.NOT_FOUND, 400, "이미 존재하는 이메일입니다."),
CREATE_KEYCLOAK_USER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 500, "인가 서버 유저 등록에 실패했습니다."),
ADD_USER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 500, "API 서버 유저 등록에 실패했습니다."),

//partner
PARTNER_NOT_FOUND(HttpStatus.NOT_FOUND, 404, "파트너 회원 정보를 찾을 수 없습니다."),
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/org/example/commerce_site/config/KeycloakConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.example.commerce_site.config;

import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class KeycloakConfig {
@Value("${oauth.keycloak.realm}")
private String REALM;

@Value("${oauth.keycloak.auth-server-url}")
private String AUTH_SERVER_URL;

@Value("${oauth.keycloak.credentials.client}")
private String CLIENT;

@Value("${oauth.keycloak.credentials.secret}")
private String CLIENT_SECRET;

@Bean
public Keycloak keycloak() {
return KeycloakBuilder.builder()
.serverUrl(AUTH_SERVER_URL)
.realm(REALM)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(CLIENT)
.clientSecret(CLIENT_SECRET)
.build();
}
}
48 changes: 48 additions & 0 deletions src/main/java/org/example/commerce_site/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.example.commerce_site.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
private static final String[] AUTH_EXCLUDE_POST_API_LIST = {"/user/keycloak/webhook"};
private static final String[] AUTH_EXCLUDE_GET_API_LIST = {"/auth/**"};
private static final String[] AUTH_EXCLUDE_WEB_LIST = {"/swagger-ui/**", "/api-docs/**"};

@Bean
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();

http
.csrf(AbstractHttpConfigurer::disable)
.cors(Customizer.withDefaults())
.authorizeHttpRequests(requests -> requests
.requestMatchers(HttpMethod.POST, AUTH_EXCLUDE_POST_API_LIST).permitAll()
.requestMatchers(HttpMethod.GET, AUTH_EXCLUDE_GET_API_LIST).permitAll()
.requestMatchers(AUTH_EXCLUDE_WEB_LIST).permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(
oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter)))
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin));

return http.build();
}
}
2 changes: 1 addition & 1 deletion src/main/java/org/example/commerce_site/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
@AllArgsConstructor
@Table(name = "users")
public class User extends BaseTimeEntity {
private String authId;
private String name;
private String email;
private String password;
@Enumerated(EnumType.STRING)
private UserStatus status;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package org.example.commerce_site.infrastructure.user;

import java.util.Optional;

import org.example.commerce_site.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.example.commerce_site.representation.auth;

import org.example.commerce_site.application.auth.KeycloakAuthService;
import org.example.commerce_site.application.auth.dto.OAuthAccessTokenResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
public class AuthController {
private final KeycloakAuthService keycloakAuthService;

@GetMapping("/callback")
public OAuthAccessTokenResponse.Keycloak auth(@RequestParam String code) {
return keycloakAuthService.getAccessToken(code);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package org.example.commerce_site.representation.user;

import org.example.commerce_site.application.user.UserService;
import org.example.commerce_site.common.response.ApiSuccessResponse;
import org.example.commerce_site.representation.user.request.UserRequest;
import org.example.commerce_site.representation.user.response.UserResponse;
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 jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -20,9 +17,8 @@
public class UserController {
private final UserService userService;

@PostMapping()
public ApiSuccessResponse<UserResponse.Create> createUser(@Valid @RequestBody UserRequest.Create request) {
return ApiSuccessResponse.success(
UserResponse.Create.of(userService.create(UserRequest.Create.toDTO(request))));
@PostMapping("/keycloak/webhook")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 주소가 외부에 노출되면 어떻게 될까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉.. 생각해보지 못했습니다..
이럴 경우 admin 계정같은걸 만들고 웹훅을 보내는 쪽에서 어드민 계정의 토큰을 발급받아 해당 토큰으로 hook api 를 호출하도록 하면 될까요..?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네, 해당 방법도 하나의 좋은 방법이 될 것 같습니다. 추가적으로 더 조치할 방법은 없는지 좀 더 찾아보면 좋을 것 같습니다.

Copy link
Collaborator Author

@ohsuha ohsuha Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. @RequestHeader("X-API-KEY") 를 통해 리퀘스트 헤더에 미리 지정한 키를 설정하는 방식
  2. Keycloak이 요청을 보내는 서버의 IP 주소만 허용하도록 제한하는 방식

이렇게 두가지 방식을 더 찾아봤는데 1번을 사용하도록 수정했습니다!

public void createUser(@RequestBody UserRequest.Create request) {
userService.create(UserRequest.Create.toDTO(request));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,22 @@

import org.example.commerce_site.application.user.dto.UserRequestDto;

import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.ToString;

public class UserRequest {
@Getter
@ToString
public static class Create {
@NotBlank
private String name;
@NotBlank
//TODO email 형식 체크
private String id;
private String userName;
private String email;
@NotBlank
//TODO 패스워드 형식 체크 (8자리 이상 20자리 이하 영문 + 숫자)
private String password;

public static UserRequestDto.Create toDTO(UserRequest.Create request) {
return UserRequestDto.Create.builder()
.name(request.getName())
.id(request.getId())
.name(request.getUserName())
.email(request.getEmail())
//TODO PWD 암호화
.password(request.getPassword())
.build();
}
}
Expand Down
17 changes: 17 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ spring:
locations: classpath:db/migration/mysql
jackson:
property-naming-strategy: SNAKE_CASE
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: http://localhost:9090/realms/oauth2/protocol/openid-connect/certs
issuer-uri: http://localhost:9090/realms/oauth2
server:
port: 8080
forward-headers-strategy: framework
Expand All @@ -39,3 +45,14 @@ springdoc:
default-produces-media-type: application/json;charset=UTF-8
default-consumes-media-type: application/json;charset=UTF-8
server-url: http://localhost:8080
oauth:
keycloak:
realm: oauth2
auth-server-url: http://localhost:9090
credentials:
client: oauth2-client-app
secret: 6buMCUOwLIjBhRE6oJ7TNklkIhPqyCl5
grant-type: authorization_code
uri:
redirect: http://localhost:8080/auth/callback
token: http://localhost:9090/realms/oauth2/protocol/openid-connect/token
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE ecommerce_site.users DROP COLUMN password;
ALTER TABLE ecommerce_site.users ADD auth_id varchar(255) NOT NULL;
ALTER TABLE ecommerce_site.users CHANGE auth_id auth_id varchar(255) NOT NULL AFTER id;
ALTER TABLE ecommerce_site.users ADD CONSTRAINT users_unique UNIQUE KEY (auth_id);
Loading