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

cod*_*ape 5 java spring spring-mvc spring-security spring-boot

我通过添加依赖项spring-boot-starter-oauth2-client并在application.properties.

\n

Spring Boot 和 OAuth2指南中,有一节“如何添加本地用户数据库”:

\n
\n

如何添加本地用户数据库

\n

许多应用程序需要在本地保存有关其用户的数据,即使将身份验证委托给外部提供商也是如此。我们不在这里显示代码,但只需两步即可轻松完成。

\n
    \n
  1. 为您的数据库选择一个后端,并为适合您的需要并可以从外部身份验证完全或部分填充的自定义 User 对象设置一些存储库(例如使用 Spring Data)。

    \n
  2. \n
  3. 实现并公开 OAuth2UserService 以调用授权\n服务器以及您的数据库。您的实现可以委托给\n默认实现,这将完成调用授权服务器的繁重工作。您的实现应该返回扩展您的自定义 User 对象并实现 OAuth2User 的内容。

    \n
  4. \n
\n

提示:在 User 对象中添加一个字段,以链接到外部提供程序中的唯一标识符(不是用户名\xe2\x80\x99s,而是外部提供程序中帐户的唯一标识符\xe2\x80\x99s\n) )。

\n
\n

我进行了一些搜索,但没有找到摘录中描述的场景的代码示例。

\n

实现上述场景的最佳方法是什么?

\n

我想主要部分是:

\n
    \n
  • OIDC登录时,如果数据库不存在则自动创建用户
  • \n
  • Web 应用程序控制器方法可以访问代表登录用户的数据库对象
  • \n
\n

更新:

\n

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

\n
@Bean\npublic OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService(WebClient rest) {\n    DefaultOAuth2UserService delegate = new DefaultOAuth2UserService();\n    return request -> {\n        OAuth2User user = delegate.loadUser(request);\n        if (!"github".equals(request.getClientRegistration().getRegistrationId())) {\n            return user;\n        }\n\n        OAuth2AuthorizedClient client = new OAuth2AuthorizedClient\n                (request.getClientRegistration(), user.getName(), request.getAccessToken());\n        String url = user.getAttribute("organizations_url");\n        List<Map<String, Object>> orgs = rest\n                .get().uri(url)\n                .attributes(oauth2AuthorizedClient(client))\n                .retrieve()\n                .bodyToMono(List.class)\n                .block();\n\n        if (orgs.stream().anyMatch(org -> "spring-projects".equals(org.get("login")))) {\n            return user;\n        }\n\n        throw new OAuth2AuthenticationException(new OAuth2Error("invalid_token", "Not in Spring Team", ""));\n    };\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Ana*_*kzz 1

Github 使用OAuth2UserService<OAuth2UserRequest, OAuth2User>你需要的是OAuth2UserService<OidcUserRequest, OidcUser>. 那么您是否尝试创建另一个@Bean插入弹簧期望的正确位置的对象?

如果没有,请创建一个这样的

  @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;
    };
  }
Run Code Online (Sandbox Code Playgroud)