java 带有本地用户数据库的Sping Boot oauth2

laik7k3q  于 2022-12-17  发布在  Java
关注(0)|答案(1)|浏览(85)

我已经通过添加spring-boot-starter-oauth2-client依赖项并在application.properties中配置OAuth2客户机设置,在Sping Boot Web应用程序中实现了OIDC身份验证。
Spring Boot and OAuth2指南中,有一节“如何添加本地用户数据库”:
如何添加本地用户数据库
许多应用程序需要在本地保存用户的数据,即使身份验证委托给了外部提供者,我们没有在这里显示代码,但这很容易通过两个步骤来完成。
1.为您的数据库选择一个后端,并为一个自定义User对象设置一些存储库(比如使用Spring Data),该对象适合您的需要,并且可以通过外部身份验证完全或部分地填充。
1.实现并公开OAuth2 UserService以调用授权服务器和数据库。您的实现可以委托给默认实现,默认实现将完成调用授权服务器的繁重工作。您的实现应返回扩展自定义User对象并实现OAuth2 User的内容。
提示:在User对象中添加一个字段,以链接到外部提供者中的唯一标识符(不是用户名,而是外部提供者中帐户的唯一标识符)。
我搜索了一下,但没有找到摘录中描述的场景的代码示例。
实现上述场景的最佳方法是什么?
我想主要部分是:

  • 在OIDC登录时,如果数据库中不存在用户,则自动在数据库中创建用户
  • Web应用程序控制器方法可以访问表示登录用户的数据库对象
  • 更新日期:*

该指南有一个github问题注解,建议查看指南源代码中的custom-error示例。我想第一部分(在OIDC登录时,如果用户不存在,则自动创建一个用户)可以在调用DefaultOAuth2UserService().loadUser(request)之后完成。但是第二部分呢?如何使我的定制db-backed-user-object可用于我的Web应用程序的控制器方法?

@Bean
public OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService(WebClient rest) {
    DefaultOAuth2UserService delegate = new DefaultOAuth2UserService();
    return request -> {
        OAuth2User user = delegate.loadUser(request);
        if (!"github".equals(request.getClientRegistration().getRegistrationId())) {
            return user;
        }

        OAuth2AuthorizedClient client = new OAuth2AuthorizedClient
                (request.getClientRegistration(), user.getName(), request.getAccessToken());
        String url = user.getAttribute("organizations_url");
        List<Map<String, Object>> orgs = rest
                .get().uri(url)
                .attributes(oauth2AuthorizedClient(client))
                .retrieve()
                .bodyToMono(List.class)
                .block();

        if (orgs.stream().anyMatch(org -> "spring-projects".equals(org.get("login")))) {
            return user;
        }

        throw new OAuth2AuthenticationException(new OAuth2Error("invalid_token", "Not in Spring Team", ""));
    };
}
mccptt67

mccptt671#

Github使用OAuth2UserService<OAuth2UserRequest, OAuth2User>,而你需要的是OAuth2UserService<OidcUserRequest, OidcUser>,那么你有没有尝试创建另一个@Bean来插入spring期望的正确位置呢?
如果没有,请创建一个如下所示

@Bean
  public OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
    final OidcUserService delegate = new OidcUserService();
    return (userRequest) -> {
      // Delegate to the default implementation for loading a user
      OidcUser user = delegate.loadUser(userRequest);
      log.info("User from oauth server: " + user);
      //OAuth2AccessToken accessToken = userRequest.getAccessToken();
      //Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
      //Fetch the authority information from the protected resource using accessToken
      //Map the authority information to one or more GrantedAuthority's and add it to mappedAuthorities
      //Create a copy of user using mappedAuthorities
      //Insert/update local DB
      //user = new DefaultOidcUser(mappedAuthorities, user.getIdToken(), user.getUserInfo());
      return user;
    };
  }

相关问题