spring boot rest api验证firebase jwt令牌

6xfqseft  于 2021-09-30  发布在  Java
关注(0)|答案(1)|浏览(321)

我有一个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);
    }
}
ttisahbt

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验证令牌的签名和其中的一些声明。

相关问题