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



通过添加spring-boot-starter-oauth2-client依赖项并在application.properties中配置OAuth2客户端设置,我在Spring Boot web应用程序中实现了OIDC身份验证。

在Spring Boot和OAuth2指南中;"如何添加本地用户数据库":

如何添加本地用户数据库

许多应用程序需要保存数据关于本地用户的信息,即使将身份验证委派给外部提供者。我们在这里不显示代码,但很容易做到分两步。

  1. 为数据库选择后端,并设置一些存储库(比如说,使用Spring Data(为适合您的需要并且可以完全或部分从外部填充身份验证。

  2. 实现并公开OAuth2UserService以调用Authorization服务器以及数据库。您的实施可以委托给默认实现,它将完成繁重的调用授权服务器。您的实现应该返回一些东西扩展您的自定义User对象并实现OAuth2User。

提示:在User对象中添加一个字段以链接到中的唯一标识符外部提供者(不是用户名,而是对于外部提供商中的帐户是唯一的(。

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

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

我想主要部分是:

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

更新:

该指南有一个github问题注释,建议查看指南源代码中的custom-error示例。我想第一部分(在OIDC登录时,如果不存在用户,则自动创建一个用户(可以在调用DefaultOAuth2UserService().loadUser(request)之后完成。但是第二部分呢?如何使我的自定义数据库支持的用户对象可用于我的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", ""));
};
}

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;
};
}

我正在为同样的场景而挣扎,但我会添加一些需求:

  • DB状态应该用";几乎";每个请求。这是必要的,例如:向用户添加角色应该立即得到反映

到目前为止,我的发现是:

  1. 自定义OAuth2UserService很好,但它是在会话构建过程中执行的,并不是每次请求都刷新它
  2. 似乎必须要有一个自定义过滤器来完成此操作

其他人是如何处理的?

相关内容

  • 没有找到相关文章

最新更新