by Anonymous » 22 Feb 2025, 01:30
Ich implementiere die OAuth2 -Anmeldung in meiner Spring Boot 3 -Anwendung mit GitHub als Authentifizierungsanbieter. Ich kann jedoch nicht die E -Mail des Benutzers von GitHub abrufen - es kehrt immer NULL zurück. Ich werde auf die Onboarding-Seite geleitet, auf der sie Details wie UserType-Recruiter oder Jobseeker usw. eingeben Umfang: < /p>
Code: Select all
yaml
Copy
Edit
security:
oauth2:
client:
registration:
github:
client-id: xxx
client-secret: xxx
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
scope: user:email
< /code>
Einstellungen für Github -Profile geprüft: < /p>
Meine E -Mail ist in GitHub auf "public" gesetzt. BR /> Das E -Mail -Feld fehlt (NULL), andere Details wie Name und ID sind verfügbar. Warum ist es Githubs OAuth2 -Antwort ohne die E -Mail, auch wenn meine E -Mail öffentlich ist? Hier ist, wie ich versucht habe, Benutzerdetails aus dem Zugriffs-Token zu holen.@Service
@RequiredArgsConstructor
public class CustomOauth2UserService extends DefaultOAuth2UserService {
private static final Logger log = LoggerFactory.getLogger(CustomOauth2UserService.class);
private final UserConnectedAccountRepository userConnectedAccountRepository;
private final UserRepository userRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(userRequest);
String provider = userRequest.getClientRegistration().getRegistrationId();
String providerId = oAuth2User.getName();
String email = oAuth2User.getAttribute("email");
oAuth2User.getAttributes().forEach((key, value) -> log.info("key {}, value {}", key, value));
Optional userConnectedAccount = userConnectedAccountRepository.findByProviderIdAndProvider(providerId, provider);
if (userConnectedAccount.isEmpty()) {
userRepository.findUserByEmail(email)
.ifPresentOrElse(user -> connectAccount(providerId, provider, user),
() -> createUser(providerId, provider, oAuth2User)
);
}
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(null)),
oAuth2User.getAttributes(),
"email"
);
}
public void createUser(String providerId, String provider, OAuth2User oAuth2User) {
AppUser appUser = new AppUser(oAuth2User);
appUser = userRepository.save(appUser);
connectAccount(providerId, provider, appUser);
}
private void connectAccount(String providerId, String provider, AppUser appUser) {
UserConnectedAccount newUserConnectedAccount = new UserConnectedAccount(providerId, provider, appUser);
userConnectedAccountRepository.save(newUserConnectedAccount);
}
}
< /code>
Und hier ist meine Sicherheitskonfiguration. Ich verwende eine Sitzungsbasis-Authentifizierung.@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig {
private final UserService userService;
private final PasswordEncoder passwordEncoder;
private final GlobalAuthenticationEntryPoint globalAuthenticationEntryPoint;
private final Oauth2LoginSuccessHandler oauth2LoginSuccessHandler;
private final CustomOauth2UserService customOauth2UserService;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(request -> request
.requestMatchers("/api/v1/auth/**", "/login/**", "/**", "/oauth2/authorization/**").permitAll()
.anyRequest().authenticated());
http.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable)
.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfo -> userInfo.userService(customOauth2UserService))
.successHandler(oauth2LoginSuccessHandler)
);
http.exceptionHandling(customizer ->
customizer.authenticationEntryPoint(globalAuthenticationEntryPoint)
);
return http.build();
}
@Bean
public AuthenticationManager authenticationManager() {
var authenticationProvider = new DaoAuthenticationProvider(passwordEncoder);
authenticationProvider.setUserDetailsService(userService);
return new ProviderManager(authenticationProvider);
}
@Bean
public SecurityContextRepository SecurityContextRepository() {
return new HttpSessionSecurityContextRepository();
}
@Bean
public SecurityContextLogoutHandler securityContextLogoutHandler() {
return new SecurityContextLogoutHandler();
}
}
Ich implementiere die OAuth2 -Anmeldung in meiner Spring Boot 3 -Anwendung mit GitHub als Authentifizierungsanbieter. Ich kann jedoch nicht die E -Mail des Benutzers von GitHub abrufen - es kehrt immer NULL zurück. Ich werde auf die Onboarding-Seite geleitet, auf der sie Details wie UserType-Recruiter oder Jobseeker usw. eingeben Umfang: < /p>
[code]yaml
Copy
Edit
security:
oauth2:
client:
registration:
github:
client-id: xxx
client-secret: xxx
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
scope: user:email
< /code>
Einstellungen für Github -Profile geprüft: < /p>
Meine E -Mail ist in GitHub auf "public" gesetzt. BR /> Das E -Mail -Feld fehlt (NULL), andere Details wie Name und ID sind verfügbar. Warum ist es Githubs OAuth2 -Antwort ohne die E -Mail, auch wenn meine E -Mail öffentlich ist? Hier ist, wie ich versucht habe, Benutzerdetails aus dem Zugriffs-Token zu holen.@Service
@RequiredArgsConstructor
public class CustomOauth2UserService extends DefaultOAuth2UserService {
private static final Logger log = LoggerFactory.getLogger(CustomOauth2UserService.class);
private final UserConnectedAccountRepository userConnectedAccountRepository;
private final UserRepository userRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(userRequest);
String provider = userRequest.getClientRegistration().getRegistrationId();
String providerId = oAuth2User.getName();
String email = oAuth2User.getAttribute("email");
oAuth2User.getAttributes().forEach((key, value) -> log.info("key {}, value {}", key, value));
Optional userConnectedAccount = userConnectedAccountRepository.findByProviderIdAndProvider(providerId, provider);
if (userConnectedAccount.isEmpty()) {
userRepository.findUserByEmail(email)
.ifPresentOrElse(user -> connectAccount(providerId, provider, user),
() -> createUser(providerId, provider, oAuth2User)
);
}
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(null)),
oAuth2User.getAttributes(),
"email"
);
}
public void createUser(String providerId, String provider, OAuth2User oAuth2User) {
AppUser appUser = new AppUser(oAuth2User);
appUser = userRepository.save(appUser);
connectAccount(providerId, provider, appUser);
}
private void connectAccount(String providerId, String provider, AppUser appUser) {
UserConnectedAccount newUserConnectedAccount = new UserConnectedAccount(providerId, provider, appUser);
userConnectedAccountRepository.save(newUserConnectedAccount);
}
}
< /code>
Und hier ist meine Sicherheitskonfiguration. Ich verwende eine Sitzungsbasis-Authentifizierung.@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig {
private final UserService userService;
private final PasswordEncoder passwordEncoder;
private final GlobalAuthenticationEntryPoint globalAuthenticationEntryPoint;
private final Oauth2LoginSuccessHandler oauth2LoginSuccessHandler;
private final CustomOauth2UserService customOauth2UserService;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(request -> request
.requestMatchers("/api/v1/auth/**", "/login/**", "/**", "/oauth2/authorization/**").permitAll()
.anyRequest().authenticated());
http.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable)
.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfo -> userInfo.userService(customOauth2UserService))
.successHandler(oauth2LoginSuccessHandler)
);
http.exceptionHandling(customizer ->
customizer.authenticationEntryPoint(globalAuthenticationEntryPoint)
);
return http.build();
}
@Bean
public AuthenticationManager authenticationManager() {
var authenticationProvider = new DaoAuthenticationProvider(passwordEncoder);
authenticationProvider.setUserDetailsService(userService);
return new ProviderManager(authenticationProvider);
}
@Bean
public SecurityContextRepository SecurityContextRepository() {
return new HttpSessionSecurityContextRepository();
}
@Bean
public SecurityContextLogoutHandler securityContextLogoutHandler() {
return new SecurityContextLogoutHandler();
}
}
[/code]