现有表单登录应用程序中具有 OAuth2 的自定义主体

Posted

技术标签:

【中文标题】现有表单登录应用程序中具有 OAuth2 的自定义主体【英文标题】:Custom Principal with OAuth2 in existing form login application 【发布时间】:2021-12-02 21:47:24 【问题描述】:

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

我所有的控制器都依赖于我的 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);
  

有什么想法吗?

【问题讨论】:

【参考方案1】:

终于解决了这个返回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);

【讨论】:

以上是关于现有表单登录应用程序中具有 OAuth2 的自定义主体的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot OAuth2 自定义登录表单用例

Spring Security 5 中使用 oauth2 的自定义登录页面返回 null

使用 oAuth2.0 和表单登录的 Spring Security

具有 OAuth2-ResourceServer 的 Spring 微服务仅返回 String 作为主体而不是我的自定义用户

如何有单独的身份验证源? (一个用于 Oauth2,一个用于基于表单的登录)

是否可以使用jsp登录表单作为spring security的自定义登录表单