我正在尝试使用 Keycloak 作为集中授权服务器将 Vaadin 前端连接到后端 API。
目前我有一个用 FastAPI 编写的 API 服务,可用于提交数据并在数据处理后接收分析结果。结果存储在每个租户/用户组的不同数据库模式中。 该 API 应该用于以多种方式集成服务,例如其他应用程序。
现在我想为 Vaadin 提供一个用户界面,以便非技术用户更容易使用我的 API 功能。我想允许使用 Keycloak 中存储的凭据登录应用程序。 我之前曾在另一个普通 Java 应用程序中使用过 Vaadin,但我对使用 Spring、Spring Security 和 OAuth2/Keycloak 还不熟悉。
我认为流程应该是:
我设法为关注这些博客的用户实现登录: https://martinelli.ch/vaadin-oauth2-and-keycloak/ https://rene-wilby.de/blog/hilla-oauth-authorization-code-flow-keycloak/
@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends VaadinWebSecurity {
private final KeycloakLogoutHandler keycloakLogoutHandler;
public SecurityConfiguration(KeycloakLogoutHandler keycloakLogoutHandler) {
this.keycloakLogoutHandler = keycloakLogoutHandler;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(
authorize -> authorize.requestMatchers(new AntPathRequestMatcher("/images/*.png")).permitAll());
// Icons from the line-awesome addon
http.authorizeHttpRequests(authorize -> authorize
.requestMatchers(new AntPathRequestMatcher("/line-awesome/**/*.svg")).permitAll());
http.oauth2Login(Customizer.withDefaults()).logout( logout ->
logout.addLogoutHandler(keycloakLogoutHandler)
);
super.configure(http);
setOAuth2LoginPage(http, "/oauth2/authorization/keycloak");
}
@Bean
public GrantedAuthoritiesMapper userAuthoritiesMapperForKeycloak() {
return authorities -> {
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
var authority = authorities.iterator().next();
if (authority instanceof OidcUserAuthority oidcUserAuthority) {
var userInfo = oidcUserAuthority.getUserInfo();
if (userInfo.hasClaim("realm_access")) {
var realmAccess = userInfo.getClaimAsMap("realm_access");
var roles = (Collection<String>) realmAccess.get("roles");
mappedAuthorities.addAll(roles.stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role.toUpperCase()))
.toList());
}
}
return mappedAuthorities;
};
}
}
我收到 OicdUser 并能够访问其信息。但是,OicdUser 仅包含 ID-Token,这不是应该发送到 API 的内容(根据我的理解)。
如何接收访问令牌并使用它向后端 API 发出请求? 这是解决问题的正确方法还是我有一些误解?
提前致谢!
您可以从
OAuth2AuthorizedClientManager
bean 获取访问令牌。
要查询资源服务器,您需要一个 REST 客户端,可能是
RestClient
、WebClient
、RestTemplate
和 @FeignClient
之一(最后两个处于维护模式,因此在新集成中应该避免使用) )。所有这些都有自己的与授权客户集成的说明,请参阅您选择的客户的文档。
我刚刚编写的这个入门程序为 OAuth2 授权提供了一些自动配置,包括
RestClient
和 WebClient
。你可以尝试一下。