我有一个springboot rest应用程序,我正试图用firebase保护它,其用户身份验证流程如下:
用户使用firebase auth在单独的vue前端进行身份验证,并获取firebase jwt id令牌。
前端将auth头中的此令牌发送到我的后端。
然后,我的后端应该获取令牌,并通过将令牌发送到firebase服务器进行身份验证。
如果令牌有效,则返回用户请求的任何资源,而不返回401。
我已经配置了前端代码,现在正在发送每个请求的jwt令牌。我正在尝试设置后端,但遇到了一些问题。
我已将firebase sdk管理员添加到我的应用程序中,初始化了firebase应用程序,并实现了http筛选器来过滤所有检查和验证令牌的请求。我一直在关注firebase关于令牌身份验证的教程。出于某种原因,我所有的请求都返回403?我不确定我的实现出了什么问题,因为没有错误需要修复。
我的pom xml代码段:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>7.3.0</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<version>1.39.2</version>
</dependency>
用于初始化firebase sdk的my firebase类:
@Service
public class FirebaseInitialization {
@PostConstruct
public void initialization() {
try{
FileInputStream inputStream = new FileInputStream("src/main/resources/serviceAccountKey.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(inputStream))
.build();
FirebaseApp.initializeApp(options);
}
catch (Exception error) {
error.printStackTrace();
}
}
}
我的安全配置类:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_WHITELIST = {"/publicEndpoint"};
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and()
.csrf().disable()
.addFilterAfter(new FireBaseTokenFilter(), FireBaseTokenFilter.class)
.sessionManagement().sessionCreationPolicy(STATELESS).and()
.authorizeRequests()
.antMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().authenticated();
http.headers().frameOptions().disable();
}
}
检查firebase令牌的我的http筛选器:
public class FireBaseTokenFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String authenticationHeader = request.getHeader("Authorization");
//checks if token is there
if (authenticationHeader == null || !authenticationHeader.startsWith("Bearer "))
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED,"Missing token!");
FirebaseToken decodedToken = null;
try {
//Extracts token from header
String token = authenticationHeader.substring(7, authenticationHeader.length());
//verifies token to firebase server
decodedToken = FirebaseAuth.getInstance().verifyIdToken(token);
}
catch (FirebaseAuthException e) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED,"Error! "+e.toString());
}
//if token is invalid
if (decodedToken==null){
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED,"Invalid token!");
}
chain.doFilter(request,response);
}
}
1条答案
按热度按时间ttisahbt1#
您得到403响应,这意味着您的筛选器没有运行(筛选器中的所有响应都是401响应)。如果您查看您的配置,在这一行:
.addFilterAfter(new FireBaseTokenFilter(), FireBaseTokenFilter.class)
您告诉spring注册一个新的firebasetokenfilter,它应该在firebasetokenfilter之后调用。这将不起作用,因为您尚未注册firebase筛选器。如果你把那行改成
addFilterBefore(new FireBaseTokenFilter(), UsernamePasswordAuthenticationFilter.class)
现在将调用过滤器。不过,您仍然需要一种方法来告诉spring用户已通过身份验证。您的过滤器将拒绝带有无效令牌的请求,但我认为它仍然会拒绝带有有效令牌的请求。请看一看关于在spring中保护API的本教程,以检查如何配置资源服务器以接受jwts。还请注意,firebase sdk验证id令牌,但没有调用firebase server。sdk验证令牌的签名和其中的一些声明。