How to authenticate requests by COOKIE in JHipster v8.1.0

61 Views Asked by At

I recently switched to JHipster v8.1.0 but cannot figure out how to authenticate incoming requests by their cookies.

In version 7.x.x there was a JWTFilter class and inside of it there was a resolveToken(HttpServletRequest request) method and with that, I could easily resolve the token from cookie or header...

This was my version of the resolveToken function in older versions to resolve the JWT token from the cookie:

private String resolveToken(HttpServletRequest request) {
    String bearerToken = request.getHeader(AUTHORIZATION_HEADER);
    if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
        return bearerToken.substring(7);
    }
    final Cookie auth = WebUtils.getCookie(request, AUTHORIZATION_COOKIE);
    if (auth != null && StringUtils.hasText(auth.getValue())) {
        return auth.getValue();
    }
    return null;
}

But in the new version, I cannot find a way to do that. What can I try next?

1

There are 1 best solutions below

0
Soroush Shemshadi On BEST ANSWER

Because of not finding any answer on the internet or here I tried to somehow do my own trick.

As much as the way I did it seems good I hope the Jhipster crew gives the developers some interface so that they could choose their own authorization method.

Ok so I implemented a filter to extract the possible token in the cookie then added it to headers and then added this filter before UsernamePasswordAuthenticationFilter:

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.GenericFilterBean;
import org.springframework.web.util.WebUtils;
import tech.siloxa.magineh.security.SecurityUtils;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Component
public class CookieAuthorizationFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        final MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(httpServletRequest);

        final Cookie cookie = WebUtils.getCookie(httpServletRequest, "Authorization");
        if (cookie != null && StringUtils.hasText(cookie.getValue())) {
            mutableRequest.putHeader("Authorization", "Bearer " + URLDecoder.decode(cookie.getValue(), StandardCharsets.UTF_8));
        }

        filterChain.doFilter(mutableRequest, servletResponse);
    }

    public static final class MutableHttpServletRequest extends HttpServletRequestWrapper {

        private final Map<String, String> customHeaders;

        public MutableHttpServletRequest(HttpServletRequest request) {
            super(request);
            this.customHeaders = new HashMap<>();
        }

        public void putHeader(String name, String value) {
            this.customHeaders.put(name, value);
        }

        public String getHeader(String name) {
            String headerValue = customHeaders.get(name);

            if (headerValue != null) {
                return headerValue;
            }
            return ((HttpServletRequest) getRequest()).getHeader(name);
        }

        public Enumeration<String> getHeaderNames() {
            Set<String> set = new HashSet<>(customHeaders.keySet());

            Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaderNames();
            while (e.hasMoreElements()) {
                String n = e.nextElement();
                set.add(n);
            }

            return Collections.enumeration(set);
        }
    }
}

And in SecurityConfiguration :

@Configuration
@EnableMethodSecurity(securedEnabled = true)
public class SecurityConfiguration {

    private final JHipsterProperties jHipsterProperties;
    private final CookieAuthorizationFilter cookieAuthorizationFilter;

    public SecurityConfiguration(JHipsterProperties jHipsterProperties,
                                 CookieAuthorizationFilter cookieAuthorizationFilter) {
        this.jHipsterProperties = jHipsterProperties;
        this.cookieAuthorizationFilter = cookieAuthorizationFilter;
    }

    // some codes

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception {
        http
            // some codes
            .addFilterBefore(cookieAuthorizationFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

Hope this will help.