Spring Security using HTTP headers

Viewed 30976

I am trying to add security to my Spring Boot application. My current application is using REST controllers and every time I get a GET or POST request I read the HTTP header to retrieve the user and password in order to validate them against the properties file I have all my users stored. I want to change this to using Spring Security and this is what I got so far:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/index.html").permitAll()
            .antMatchers("/swagger-ui.html").hasRole("ADMIN")
            .anyRequest().authenticated();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("admin").password("password").roles("ADMIN").build());
    }
}

How can I tell the configure method that the user credentials are to be retrieved from the header and not a login form?

4 Answers

the minimal code addition is to define a filter and add it to the security configuration, smth like

XHeaderAuthenticationFilter.java

@Component
public class XHeaderAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        String xAuth = request.getHeader("X-Authorization");

        User user = findByToken(xAuth);

        if (user == null) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token invalid");
        } else {
            final UsernamePasswordAuthenticationToken authentication =
                    new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);

            filterChain.doFilter(request, response);
        }
    }

    //need to implement db user validation...
    private User findByToken(String token) {
        if (!token.equals("1234"))
            return null;

        final User user = new User(
                "username",
                "password",
                true,
                true,
                true,
                true,
                Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")));

        return user;
    }
}

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(final HttpSecurity http) throws Exception {
            http.sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .csrf().disable()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .exceptionHandling()
                    .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
                .and()
                .addFilterBefore(new XHeaderAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        }
}

another approach is to use spring's AOP to define annotation of some logic to perform before entering the annotated controller method

Related