Authenticate API Requests in Spring using Firebase Auth

梦想与她 提交于 2021-02-20 04:37:52

问题


Im already authenticating access to my API using a Firebase Auth token (JWT) which is passed inside the Http Authorization Header as Bearer token. This works fine using auto configuration. Now I want to map from the authentication to a user record in my DB. How do I need to adapt the security filter chain? This configuration is automatically applied by spring boot according to the docs and can be overridden:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests().anyRequest().authenticated()
            .and().oauth2ResourceServer().jwt();
}

I am using the Firebase Authentication UI drop in solution which provides the access token on a successful authentication. This token then gets passed to my API.


回答1:


There are a few things you may need to do:

  1. Write a security filter to call FirebaseAuth to authenticate the Bearer Token. Once the token is authenticated, put it into the SecurityContext. Something similar as:
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);
    }
}
  1. You will need an implementation of UserDetailsService, which I believe you already have.

  2. You will need a security provider which get the authentication from the security context, then call out UserDetailsService to obtain whatever information you may need for your application. Then update the authentication object. Something similar as:

@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));
    }

}

Hope above helps.



来源:https://stackoverflow.com/questions/57707204/authenticate-api-requests-in-spring-using-firebase-auth

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!