【问题标题】:Authenticate API Requests in Spring using Firebase Auth使用 Firebase Auth 在 Spring 中验证 API 请求
【发布时间】:2020-01-02 13:19:08
【问题描述】:
我已经使用 Firebase 身份验证令牌 (JWT) 验证对我的 API 的访问,该令牌作为承载令牌在 Http 授权标头中传递。使用自动配置可以正常工作。现在我想从身份验证映射到我的数据库中的用户记录。我需要如何调整安全过滤器链?这个配置是spring boot根据docs自动应用的,可以覆盖:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().anyRequest().authenticated()
.and().oauth2ResourceServer().jwt();
}
我正在使用 Firebase 身份验证 UI 插件解决方案,该解决方案在成功身份验证时提供访问令牌。然后这个令牌被传递给我的 API。
【问题讨论】:
标签:
java
firebase
spring-boot
spring-security
firebase-authentication
【解决方案1】:
您可能需要做一些事情:
- 编写一个安全过滤器来调用 FirebaseAuth 来验证 Bearer Token。令牌通过身份验证后,将其放入 SecurityContext。类似于:
public class FirebaseFilter extends OncePerRequestFilter {
private static String AUTH_HEADER = "Authorization";
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String authToken = request.getHeader(AUTH_HEADER).substring(7);
if (!StringUtils.isEmpty(authToken)) {
Authentication auth = getAuthentication(authToken);
SecurityContextHolder.getContext().setAuthentication(auth);
logger.debug("Successfully Authenticated");
}
filterChain.doFilter(request, response);
}
private FirebaseToken verifyIdToken(String idToken) {
if (StringUtils.isEmpty(idToken)) {
throw new IllegalArgumentException("idToken is blank");
}
return FirebaseAuth.getInstance().verifyIdToken(idToken);
}
private Authentication getAuthentication(String idToken) {
FirebaseToken token = verifyIdToken(idToken);
assert token != null;
return new FirebaseAuthenticationToken(token.getUid(), token);
}
}
您将需要 UserDetailsService 的实现,我相信您已经拥有了。
您将需要一个从安全上下文中获取身份验证的安全提供程序,然后调用 UserDetailsService 以获取您的应用程序可能需要的任何信息。然后更新身份验证对象。类似于:
@Component
public class FirebaseAuthenticationProvider implements AuthenticationProvider {
private UserService userService;
@Autowired
public FirebaseAuthenticationProvider(UserService userService) {
this.userService = userService;
}
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (!supports(authentication.getClass())) {
return null;
}
UserDetails details = userService.loadUserByUsername(authentication.getPrincipal()
.toString());
FirebaseToken token = (FirebaseToken) authentication.getCredentials();
if (details == null) {
details = userService.registerUser(token);
}
return new FirebaseAuthenticationToken(details, token, details.getAuthorities());
}
public boolean supports(Class<?> authentication) {
return (FirebaseAuthenticationToken.class.isAssignableFrom(authentication));
}
}
希望以上有所帮助。