spring-bootjwttoken

How can I implement access tokens for a public Spring Boot API?


I have a public facing API created with Spring Boot. I want users of the API to include a token with requests so that I can ensure they are allowed to access it and also track how many requests are made within a certain period of time.

I'm a little confused on how to approach this because everything I am reading online is where a user sends their user/password and the application returns a token. This is not what I'm looking for.

I want something similar to when you use Google APIs or similar APIs where your token never changes unless you want it to change and you do not send Google API your user/pass on the first request.

Maybe I'm not using the correct terminology. Can someone point me in the right direction?


Solution

  • If you want to authenticate using a static token for each user you will have to create a custom AuthenticationManager that gets your request header and tries to match it aginst known keys.

    Example using single key, you'd have to add a lookup to user table if needed

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception
        {
        http.authorizeRequests(auth -> auth
            .anyRequest().authenticated());
    
        http.addFilter(tokenFilter());
        http.csrf().disable();
            
        return http.build();
    }
    
    
    public Filter tokenFilter()
    {
        AuthenticationTokenFilter filter = new AuthenticationTokenFilter(authenticationTokenHeader);
        filter.setAuthenticationManager(authenticationManager());
    
        return filter;
    }
    
    
    protected AuthenticationManager authenticationManager()
    {
        final AuthenticationManager authenticationManager = new AuthenticationManager()
        {
            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException
            {
                String principal = (String) authentication.getPrincipal();
                if (!authenticationTokenValue.equals(principal))
                {
                    throw new BadCredentialsException("The API key was not found or not the expected value.");
                }
                authentication.setAuthenticated(true);
                return authentication;
            }
        };
        return authenticationManager;
    }
    

    Do keep in mind that this approach is not the most secure, and if you'r application is public facing I would not recommend using this. And would recommend either using Authorization header with username/password or JWT


    As a side note, I think you'r mistaken on how the google API authenticates. To the best of my knowledge all google APIs use Oauth2 for authentication, the static key/file you have does not provide access to the API it is only good for retrieving a short lived access token, in essence this would be not much different from standard JWT where you use some form of credentials to get a token with which you access the API.

    for more info on JWT authentication: