在现有表单登录应用程序中使用 OAuth2 自定义委托人

Custom Principal with OAuth2 in existing form login application

我正在尝试将 OAuth2 登录添加到现有的表单登录应用程序。到目前为止,我已经添加了使 Google 身份验证工作所需的配置,目标是使现有 username/password 用户(或新用户)能够以两种方式登录。

我所有的控制器都依赖于我的 UserDetails 实现:

public class User implements UserDetails {
  
  private Long id;
  private String email;
  private String password;

  private String googleAccessToken;

  // ...

我可以像这样在控制器中获取登录用户:

@GetMapping
public String index(@AuthenticationPrincipal User user, Model model) {

所以我所做的是实现我的自定义 OAuth2UserService 以从数据库中获取现有用户,但我找不到将 User 设置为主体的方法。

在以前的 OAuth2 集成版本中,似乎存在一个基于 PrincipalExtractor 的更简单的解决方案,但它不再可用。

@Service
@RequiredArgsConstructor
public class OAuth2UserDetailsService implements OAuth2UserService<OidcUserRequest, OidcUser> {

  private final UsersRepository usersRepository;

  @Override
  public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
    final OidcUserService delegate = new OidcUserService();
    User user;

    // Delegate to the default implementation for loading a user
    OidcUser oidcUser = delegate.loadUser(userRequest);

    switch (userRequest.getClientRegistration().getClientName()) {
      case "google":
        user = usersRepository.findOneByGoogleAccessToken(userRequest.getAccessToken());
        break;
      default:
        throw new OAuth2AuthenticationException(new OAuth2Error("invalid_token"));
    }

    // here I should return my user principal
    return new DefaultOidcUser(null, null);
  }

有什么想法吗?

终于解决了返回 OidcUser:

实例的问题
public class UserPrincipal implements UserDetails, OidcUser {
  // ...
}

并且在 OAuth2UserService:

@Override
public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
  final OidcUserService delegate = new OidcUserService();
  User user;

  // Delegate to the default implementation for loading a user
  OidcUser oidcUser = delegate.loadUser(userRequest);

  // ...
  return new UserPrincipal(user, oidcUser);
}