현재 자바와 Spring boot를 이용해서 카카오 간편 로그인을 구현하고자 하는 개발자 지망생입니다. 다름이 아니라 코드를 구현했는데도 권한이 없다는 오류가 나와서 어떻게 하면 좋을 지 궁금해서 여쭤봅니다ㅠㅠ
ID는 1035352입니다!
안녕하세요.
개발을 하다보면 수시로 에러를 겪고 외부연계하며 불특정한 문제를 겪게됩니다.
그래서
문제를 해결하기 위해 정확히 어떤 상황과 어떤 로직에서 어떤 응답코드와 에러 메시지를 받았는지 확인 할 수 있는 상황을 만드는 것이 정상작동하는 것 보다 더 중요한데요.
1035352 디벨로퍼스앱은 최근 2주간 API 호출 내역이 없습니다. 기재하신 내용만으로는 어떤 상황인지 알 수 없고
아마도 다른 디벨로퍼스앱의 앱키를 사용하셨거나 카카오측 호출 전에 개발하신 시스템에서 발생한 문제 같습니다.
위에 안내드린 것과 같이 어떤 로직에서 어떤 오류를 받았는지 정확한 에러 메시지 확인 부탁드려요.
package com.example.demo.config;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.config.annotation.web.configurers.HttpBasicConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import com.example.demo.filter.JwtAuthenticationFilter;
import com.example.demo.handler.OAuth2SuccessHandler;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
@EnableWebSecurity
@Configuration
@Configurable
@RequiredArgsConstructor
public class WebSecurityConfig {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final DefaultOAuth2UserService oAuth2UserService;
private final OAuth2SuccessHandler oAuth2SuccessHandler;
@Bean
protected SecurityFilterChain configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors(cors -> cors
.configurationSource(corsConfigurationSource())
)
.csrf(CsrfConfigurer::disable)
.httpBasic(HttpBasicConfigurer::disable)
.sessionManagement(sessionManagement -> sessionManagement
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeHttpRequests(request -> request
.requestMatchers("/", "/api/v1/auth/**", "/oauth2/**").permitAll()
.requestMatchers("/api/v1/user/**").hasRole("USER")
.requestMatchers("/api/v1/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.oauth2Login(oauth2 -> oauth2
.authorizationEndpoint(endpoint -> endpoint.baseUri("/api/v1/auth/oauth2"))
.redirectionEndpoint(endpoint -> endpoint.baseUri("/oauth2/callback/*"))
.userInfoEndpoint(endpoint -> endpoint.userService(oAuth2UserService))
.successHandler(oAuth2SuccessHandler)
)
.exceptionHandling(exceptionHandling -> exceptionHandling
.authenticationEntryPoint(new FailedAuthenticationEntryPoint())
)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
@Bean
protected CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return source;
}
}
class FailedAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getWriter().write("{\"code\": \"NP\", \"message\": \"No Permission.\"}");
}
}
(http://localhost:4040/api/v1/auth/oauth2/kakao) 이 도메인으로 실행했을 때
{
“code”: “NP”,
“message”: “No Permission.”
}
이런 메세지가 뜹니다…
카카오와 무관하게 authorizeHttpRequests 설정 문제로 보입니다.
application.yml 공유해주세요
Kakao OAuth2 설정
spring.security.oauth2.client.registration.kakao.client-id=3397016e4357226664d43edd8077275b
spring.security.oauth2.client.registration.kakao.client-secret=T8RXrS7zOTXPp0s0apKSHP5gPaTPWU7j
spring.security.oauth2.client.registration.kakao.redirect-uri={baseURI}/oauth2/callback/{registrationId}
spring.security.oauth2.client.registration.kakao.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.kakao.client-authentication-method=client_secret_post
spring.security.oauth2.client.registration.kakao.scope=profile_nickname
Kakao OAuth2 Provider 설정
spring.security.oauth2.client.provider.kakao.authorization-uri=카카오계정
spring.security.oauth2.client.provider.kakao.token-uri=https://kauth.kakao.com/oauth/token
spring.security.oauth2.client.provider.kakao.user-info-uri=https://kapi.kakao.com/v2/user/me
spring.security.oauth2.client.provider.kakao.user-name-attribute=id
해당 코드입니다!
네, 별다른 특이점은 없네요.
아래 내용 참고 하셔서 정상작동 확인 먼저 해보시겠어요?
Spring에서 카카오 로그인 사용하기 - Spring Security 5, OAuth 2 - deprecated 대응 2023년 6월 27일
네! 한번 해보겠습니다! 감사합니다 (_ _)
알려주신 내용 참고해서 작동해보았는데 KOE205 에러가 뜹니다 동의항목 오류라고 하는데 정확히 어떤 오류인지 알 수 있을까요…?
KOE205 에러는 scope 파라메터에 디벨로퍼스설정하지 않은 항목을 설정했을때 발생합니다.
application.yml에 scope를 디벨로퍼스에서 설정한 항목으로 세팅해보시겠어요?
드디어 해결됐습니다…! 친절하게 답변해주셔서 감사해요