spring-security 在现有窗体登录应用程序中使用OAuth2自定义主体

dz6r00yl  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(140)

我正在尝试将OAuth2登录添加到一个现有的表单登录应用程序中。到目前为止,我已经添加了使Google auth工作所需的配置,目标是使现有的用户名/密码用户(或新用户)能够以两种方式登录。
我的所有控制器都依赖于我的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);
  }

有什么想法吗?

wxclj1h5

wxclj1h51#

最后通过返回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);
}

相关问题