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?
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.