'How to use Firebase with Spring boot REST Application?

I have a Spring Boot REST application that depends on the authentication done in Firebase.

On the client side Firebase generates a token whereby in the Spring Boot, I need to verify the UID.

But the code is in a callback mode, so how do I implement the function so that it can finish the task?

@RequestMapping(value = "/api/restCall", method = RequestMethod.POST, 
             consumes = "application/json", produces = "application/json")
public Object restCall(@RequestBody Parameters requestBody) throws Exception {
    String idToken = requestBody.getToken();
    Task<FirebaseToken> task = FirebaseAuth.getInstance().verifyIdToken(idToken)
            .addOnSuccessListener(new OnSuccessListener<FirebaseToken>() {
            @Override
                public void onSuccess(FirebaseToken decodedToken) {
                    String uid = decodedToken.getUid();
                }
            });
    return "???"; // what return here?
}

How do I return after onSuccess? DeferredResult?



Solution 1:[1]

To integrate Firebase with Spring, below is the sample code

In new Admin SDK the process is simple just use below code snippet.

FirebaseAuth.getInstance().deleteUser(uid);
System.out.println("Successfully deleted user.");

For more detail visit this URL https://firebase.google.com/docs/auth/admin/manage-users

This is for a legacy code. First add Firbase dependency

<dependency>
    <groupId>com.google.firebase</groupId>
    <artifactId>firebase-server-sdk</artifactId>
    <version>3.0.1</version>
</dependency>

Sample Code

@Component
public class FirebaseAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    @Qualifier(value = UserServiceImpl.NAME)
    private UserDetailsService userService;

    public boolean supports(Class<?> authentication) {
        return (FirebaseAuthenticationToken.class.isAssignableFrom(authentication));
    }

    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        if (!supports(authentication.getClass())) {
            return null;
        }

        FirebaseAuthenticationToken authenticationToken = (FirebaseAuthenticationToken) authentication;
        UserDetails details = userService.loadUserByUsername(authenticationToken.getName());
        if (details == null) {
            throw new FirebaseUserNotExistsException();
        }

        authenticationToken = new FirebaseAuthenticationToken(details, authentication.getCredentials(),
                details.getAuthorities());

        return authenticationToken;
    }

}

For Complete example please gone through github below link https://github.com/savicprvoslav/Spring-Boot-starter Complete BlogPost with CRUD operation: https://medium.com/techwasti/spring-boot-firebase-crud-b0afab27b26e

Solution 2:[2]

To integrate Firebase with Spring you actually just need to configure your Spring app as a resource server and provide an URL where public keys used for verification can be downloaded.

Dependencies

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

application.yaml file:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: https://www.googleapis.com/service_accounts/v1/jwk/[email protected]
          issuer-uri: https://securetoken.google.com/${FIREBASE_APP_NAME}

Enable http.oauth2ResourceServer().jwt():

@RestController
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @GetMapping(path = "/user")
    public String test(Principal principal) {
        return principal.getName();
    }

    @Configuration
    public static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated();
            http.oauth2ResourceServer().jwt();
        }
    }

}

Then you can just use tokens provided by the Firebase for authentication:

curl --location --request GET 'http://localhost:8080/user' \
--header 'Authorization: Bearer <TOKEN>'

Here's a nice blog post on how to setup authentication and authorization flow:

Authentication with Firebase Auth and Spring Security (Sebastijan Grabar, Dec 13, 2021)

References

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Alexander