Spring Boot基于HashiCorp Vault基础认证的性能优化疑问
问题:Spring Boot集成HashiCorp Vault实现Basic认证的性能优化困惑
背景
我正在开发一个集成HashiCorp Vault的Spring Boot应用,希望通过Vault存储用户信息实现Basic Authentication(基础认证)。应用用户量仅5-10个,无需单独数据库存储用户信息。Vault的kv v1引擎中存储了用户名、BCrypt加密密码及用户角色。
初始实现:实时查询Vault认证
最初的实现逻辑是用户登录时,从Vault查询对应用户名的信息,将用户输入的密码与Vault中存储的BCrypt加密密码比对,认证通过后获取用户角色。相关实现如下:
POM依赖
<dependency> <groupId>org.springframework.vault</groupId> <artifactId>spring-vault-core</artifactId> <version>3.0.2</version> </dependency>
用户POJO类
public class VaultBasicUser { private String password; private String roles; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRoles() { return roles; } public void setRoles(String roles) { this.roles = roles; } }
自定义认证提供者
@Slf4j @Component public class BasicVaultAuthentication implements AuthenticationProvider { @Autowired private VaultTemplate vaultTemplate; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String name = authentication.getName(); String password = authentication.getCredentials().toString(); VaultResponseSupport<VaultBasicUser> vaultResponse = vaultTemplate.read("myApp/users/" + name, VaultBasicUser.class); String vaultSecret = vaultResponse.getData().getPassword(); if (vaultSecret != null) { if (BCrypt.checkpw(password, vaultSecret)) { String vaultRoles = vaultResponse.getData().getRoles(); List<GrantedAuthority> roles = new ArrayList<>(); String[] stringOfRoles = vaultRoles.split(","); for (String singleRole : stringOfRoles) { roles.add(new SimpleGrantedAuthority(singleRole.replaceAll("\s", ""))); } UserDetails principal = new User(name, password, roles); Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, roles); return auth; } else { log.info("Incorrect Credentials (Password)"); return null; } } else { log.info("Incorrect Credentials (User Not found in Vault)"); return null; } } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class ); } }
该实现可正常运行,但测试发现每次认证耗时约375ms。
优化尝试:预加载用户到内存
为优化性能,我尝试在应用启动时将Vault中的所有用户数据加载到InMemoryUserDetailsManager中,避免每次认证调用Vault API,实现代码如下:
@Bean public UserDetailsService userDetailsService(PasswordEncoder encoder) { Collection<UserDetails> allUsers = new ArrayList(); log.info("Collecting MyApp users from Vault: " + vaultConfig.getUrl()); // ***** Get All users from Vault HERE ***** VaultEndpoint vaultEndpoint; try { vaultEndpoint = VaultEndpoint.from(new URI(vaultConfig.getUrl())); VaultTemplate vaultTemplate = new VaultTemplate(vaultEndpoint, new TokenAuthentication(vaultConfig.getToken())); List<String> vaultUsers = vaultTemplate.list("myApp/users"); for (String vaultUser : vaultUsers) { VaultResponseSupport<VaultBasicUser> vaultResponse = vaultTemplate.read("myApp/users/" + vaultUser, VaultBasicUser.class); String password = vaultResponse.getData().getPassword(); String vaultRoles = vaultResponse.getData().getRoles(); log.info("Adding User: [" + vaultUser + ", " + password + ", " + vaultRoles + "]"); allUsers.add(User.withUsername(vaultUser).password(password).roles(vaultRoles).build()); } } catch (URISyntaxException ex) { log.error("Unable to read in MyApp users from Vault: " + ex.getMessage()); log.info("Adding some Default Users..."); allUsers.add(User.withUsername("myapp_admin").password(encoder.encode("adminPassword")).roles("MYADMIN").build()); allUsers.add(User.withUsername("myapp_poweruser").password(encoder.encode("powerUserPassword")).roles("MYELEVATED").build()); allUsers.add(User.withUsername("myapp_client").password(encoder.encode("clientPassword")).roles("MYUSER").build()); } } else { log.info("Authentication configured for [" + authType.getType() + "] - Not connecting to Vault!"); } return new InMemoryUserDetailsManager(allUsers); }
但测试发现认证耗时仍约370ms,并未得到优化。我的思路是否存在错误?从内存读取用户信息理应比调用Vault更快,是否存在其他性能瓶颈?
补充说明:已添加NetBeans性能分析截图,分别展示使用自定义认证提供者和InMemoryUserDetailsManager时的性能情况。
内容的提问来源于stack exchange,提问作者AcidHawk
相关产品推荐
相关产品推荐

