Adding Spring Security Login endpoint to Swagger documentation

Viewed 22

So I'm trying to have swagger doc to my project but my login endpoint doesn't show up cause I dont have an endpoint configured for it. If I try login requests from postman it works, but I can't make it work in swagger. I tried a lot of things but i have no ideea why nothing is working. I have my Security Config defined like this:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Value("${jwt.secret}")
    private String secret;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests().antMatchers("/login/**","/api/register","/swagger-ui").permitAll()
                .and()
                .authorizeRequests().antMatchers(GET, "/api/users/**").hasAnyAuthority("ADMIN")
                .and()
                .authorizeRequests().antMatchers(POST, "/api/users/**").hasAnyAuthority("ADMIN")
                .and()
                .authorizeRequests().antMatchers(POST, "/api/snippet/**").hasAnyAuthority("ADMIN",
                        "CANDIDATE", "INTERVIEWER").and()
                .authorizeRequests().antMatchers(DELETE, "/api/snippet/**").hasAnyAuthority("ADMIN",
                        "INTERVIEWER")
                .and()
                .authorizeRequests().antMatchers(DELETE, "/api/remove-snippet/**").hasAnyAuthority(
                        "ADMIN", "INTERVIEWER")
                .and()
                .authorizeRequests().antMatchers(POST, "/api/add-permission/**").hasAnyAuthority("ADMIN",
                        "INTERVIEWER")
                .and()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .apply(new CustomFilterConfiguration());
        return http.build();
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    class CustomFilterConfiguration extends AbstractHttpConfigurer<CustomFilterConfiguration, HttpSecurity> {
        @Override
        public void configure(HttpSecurity http) {
            AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
            http
                    .addFilter(new CustomAuthenticationFilter(authenticationManager,secret))
                    .addFilterBefore(new CustomAuthorizationFilter(secret), UsernamePasswordAuthenticationFilter.class);
        }
    }

}

and the Custom AuthFilter like this:


public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    private final AuthenticationManager authenticationManager;

    public static final long  TOKEN_VALIDITY_IN_MINUTES =  10 * 60;

    private final String secret;


    public CustomAuthenticationFilter(AuthenticationManager authenticationManager,String secret){
        this.secret=secret;
        this.authenticationManager=authenticationManager;

    }
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
        return authenticationManager.authenticate(authenticationToken);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException {
        CustomUserSecurity user = (CustomUserSecurity) authentication.getPrincipal();
        Algorithm algorithm = Algorithm.HMAC256(secret.getBytes());
        String access_token = JWT.create()
                .withSubject(user.getUsername())
                .withExpiresAt(new Date(System.currentTimeMillis() + TOKEN_VALIDITY_IN_MINUTES * 1000))
                .withIssuer(request.getRequestURL().toString())
                .withClaim(SecurityConstants.password, user.getUsername())
                .withClaim(SecurityConstants.loggedUserId, user.getId())
                .withClaim(SecurityConstants.roles, user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()))
                .sign(algorithm);
        Map<String, String> tokens = new HashMap<>();
        tokens.put(SecurityConstants.accessToken, access_token);
        response.setContentType(APPLICATION_JSON_VALUE);
        new ObjectMapper().writeValue(response.getOutputStream(), tokens);
    }



}

Any idea how can I implement an endpoint that works for Swagger?

Tried a lot of of things from here but nothing worked.

0 Answers
Related