K4mczi
K4mczi

Reputation: 397

Add custom claim in authentication filter. Get user id in filter. Spring boot

I want to add user's id as custom claim into my token.

But i cant get users id in filter because dependency injection isnt working in filters. I tried using constructor of my UserService but in this service i have repository which im @Autowiring so in debug mode i have seen that userRepository field is null.

My question is how i will add this custom claim? Maybe is it another way to add this.

I was following this tutorial (without "Aside" chapter) https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/#User-Authentication-and-Authorization-on-Spring-Boot

this is my filter where im trying to add this claim

package com.kamczi.auth;

import com.auth0.jwt.JWT;
import static com.auth0.jwt.algorithms.Algorithm.HMAC512;
import com.fasterxml.jackson.databind.ObjectMapper;
import static com.kamczi.auth.SecurityConstants.EXPIRATION_TIME;
import static com.kamczi.auth.SecurityConstants.HEADER_STRING;
import static com.kamczi.auth.SecurityConstants.SECRET;
import static com.kamczi.auth.SecurityConstants.TOKEN_PREFIX;
import com.kamczi.entities.User;
import com.kamczi.repository.UserRepository;
import com.kamczi.services.UserService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 *
 * @author Kamil
 */
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter   {
    private AuthenticationManager authenticationManager;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try{
            User user = new ObjectMapper()
                    .readValue(request.getInputStream(), User.class);

            return authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(
                            user.getUsername(),
                            user.getPassword(),
                            new ArrayList<>())
                    );
        } catch(IOException e){
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        String username = ((org.springframework.security.core.userdetails.User) authResult.getPrincipal()).getUsername();
        String token = JWT.create()
                //.withClaim("id", userService.findByUsername(username).getUser_id()) need implementation
                .withSubject(username)
                .withExpiresAt(new Date(System.currentTimeMillis()+EXPIRATION_TIME))
                .sign(HMAC512(SECRET.getBytes()));
        response.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
    }


}

Upvotes: 1

Views: 1869

Answers (1)

Bogdan Oros
Bogdan Oros

Reputation: 1299

Try to mark your filter with @Component. The @Autowired is working only with Spring-managed beans (components).

Or you can add the filter manually using the constructor and pass the repository to it.

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    UsersRepository usersRepo;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterAt(new JWTAuthenticationFilter(usersRepo), UsernamePasswordAuthenticationFilter.class);
    }

}

Upvotes: 1

Related Questions