mirror of
https://github.com/iflytek/skillhub.git
synced 2026-10-06 02:48:28 +00:00
fix(auth): force https scheme for requests matching the public base URL
Higress terminates TLS and forwards plain HTTP without a usable
X-Forwarded-Proto, so {baseUrl} expansion produced http:// OAuth2
redirect URIs and Secure session cookies were dropped. Rewrite the
scheme to https when the request host matches skillhub.public.base-url.
Signed-off-by: yhd <yhd4711499@live.com>
This commit is contained in:
parent
e192b94d19
commit
94baeb5544
1 changed files with 88 additions and 0 deletions
|
|
@ -0,0 +1,88 @@
|
|||
package com.iflytek.skillhub.filter;
|
||||
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
/**
|
||||
* Some TLS-terminating gateways (e.g. Higress) forward requests over plain HTTP without a
|
||||
* usable X-Forwarded-Proto, so the container reports scheme http. When the public base URL is
|
||||
* https, force the scheme back to https for requests matching the public host; otherwise
|
||||
* {baseUrl} expansion (OAuth2 redirect URIs) and Secure session cookies break.
|
||||
*/
|
||||
@Component
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 10)
|
||||
public class PublicBaseUrlSchemeFilter extends OncePerRequestFilter {
|
||||
|
||||
private final String publicHost;
|
||||
|
||||
public PublicBaseUrlSchemeFilter(@Value("${skillhub.public.base-url:}") String publicBaseUrl) {
|
||||
this.publicHost = resolveHttpsHost(publicBaseUrl);
|
||||
}
|
||||
|
||||
private static String resolveHttpsHost(String publicBaseUrl) {
|
||||
if (publicBaseUrl == null || publicBaseUrl.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
URI uri = URI.create(publicBaseUrl.trim());
|
||||
if (!"https".equalsIgnoreCase(uri.getScheme()) || uri.getHost() == null) {
|
||||
return null;
|
||||
}
|
||||
return uri.getHost().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
if (publicHost == null
|
||||
|| !"http".equals(request.getScheme())
|
||||
|| !publicHost.equals(request.getServerName().toLowerCase())) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
filterChain.doFilter(new HttpsSchemeRequest(request), response);
|
||||
}
|
||||
|
||||
private static final class HttpsSchemeRequest extends HttpServletRequestWrapper {
|
||||
|
||||
private HttpsSchemeRequest(HttpServletRequest request) {
|
||||
super(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScheme() {
|
||||
return "https";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServerPort() {
|
||||
int port = super.getServerPort();
|
||||
return port == 80 ? 443 : port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuffer getRequestURL() {
|
||||
HttpServletRequest request = (HttpServletRequest) getRequest();
|
||||
StringBuffer url = new StringBuffer("https://").append(request.getServerName());
|
||||
String uri = request.getRequestURI();
|
||||
if (uri != null) {
|
||||
url.append(uri);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue