fenrirx22 fenrirx22 - 3 years ago 162
Java Question

heroku : spring boot acces to endpoints with https only

I have a Spring Boot java app deployed on heroku. I want to be sure that my registration endpoint can be only accessed by https. So far I've known, heroku uses load balancer which redirect every https connection to http with a special header (X-forwarded-porto).
Iam using

compile("org.springframework.boot:spring-boot-starter-security")


for encryption tools (hashing password). I've set the "security.basic.enable" properties to false (actually don't know if it matters in that case.).

Tried already setting these settings :

tomcat:
remote_ip_header: x-forwarded-for
protocol_header: x-forwarded-proto


in my application.yml

The question is, how i can actually enforce endpoint to be used only via https link? For http it could return 404 or something. I am using gradle and its kinda hard to find any refference using it. Tried a couple of things found in google but it didn't work ( or I don't know how to implement them correctly...). I've still could access my endpoint via http with postman.
Right now it looks like this:

@Controller
@RequestMapping("/users")
public class AccountController {
@Autowired
private AccountRepository accountDao;

@RequestMapping(value = "/register", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Resource<Account>> createAccount(@RequestBody @Valid Account account) { ... }

Answer Source

Actually I've found a solution ( finally ) in this repo https://github.com/fenrirx22/springmvc-https-enforcer.

Created 2 classes:

@Configuration
public class ApiConfig {
    @Bean
    public Filter httpsEnforcerFilter(){
        return new HttpsEnforcer();
    }
}

and:

public class HttpsEnforcer implements Filter {

    private FilterConfig filterConfig;

    public static final String X_FORWARDED_PROTO = "x-forwarded-proto";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        if (request.getHeader(X_FORWARDED_PROTO) != null) {
            if (request.getHeader(X_FORWARDED_PROTO).indexOf("https") != 0) {
                response.sendRedirect("https://" + request.getServerName() + request.getPathInfo());
                return;
            }
        }

        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // nothing
    }
}

Works like a charm.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download