I use Restlet integration with Jetty in my project. I would need to remove the "Server" header from the response as it discloses server information. But since I use Restlet integration with Jetty (restlet, jetty, org.restlet.ext.jetty.jar) the HttpConfiguration object is instantiated inside Restlet and not in my code. So I am not able to set "_sendServerVersion" as false and hence not able to remove the server header from the response. How to remove the server header from the response in this case ?
The best way to create a Filter and remove the header through the Filter:
public class ServerFilter extends Filter {
public ServerFilter(Context context) {
super(context);
}
#Override
protected void afterHandle(Request request, Response response) {
response.getHeaders().set("Server", null);
super.afterHandle(request, response);
}
}
Then use it like:
ServerFilter serverFilter = new ServerFilter(getContext());
serverFilter.setNext(router);
return serverFilter;
See: https://javadocs.restlet.talend.com/2.4/jee/api/index.html for documentation
Related
I am quite new in Spring Cloud Feign and trying to send HTTP header which is required by service provider. Here is the code snippet
#FeignClient(name = "authentication", url = "http://localhost:3000/api")
public interface AuthenticationService {
#PostMapping(value = "/login")
JsonNode login(#RequestHeader("Origin") String origin, #RequestBody LoginParams parameters);
}
When I try to send Origin header then server does not receive this header. But other headers like referer or x-access-token are received at server successfully.
I have also tried using RequestInterceptor and was not successful to send Origin as header.
#Component
public class HeaderInterceptor implements RequestInterceptor {
#Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.removeHeader("origin");
requestTemplate.header("origin", "http://amjad.localhost:3000/");
}
}
Any hint or help would be much appreciated.
cheers!
I had similar issue with OpenFeign. "Origin" header was blocked by defult, because it was using old Java http client.
After change to OkHttp Client, "Origin" was sent.
I have a ASP.NET Core 3.1 API where I have not used CORS. As I understand, CORS is a browser thing. And as my ajax calls from another site on another origin is blocked to the API endpoints (which is great), I can still reach the same endpoints by using Postman or a HttpClient and GetAsync() calls.
My question is of it's possible to also block server-to-server calls (or Postman calls) to my API? Or like CORS, only allow certain origins?
Most of my endpoints are protected by a bearer JWT token, but I have an anonymous endpoint that I would like to let only origins I control (or can configure) to have access to that anonymous API.
I solved it after i bumped in to this post on stackoverflow:
How do you create a custom AuthorizeAttribute in ASP.NET Core?
I simply made a custom Authorize attribute [ApiAuthorize()], that I call this way:
[ApiController]
[ApiAuthorize(new string[] { "https://localhost:44351", "https://mysite.onthe.net" })]
public class MyInternalApiController : ControllerBase
{
...
}
It may also be implemented on the Action instead of the Controller. The implementation was done like this:
public class ApiAuthorizeAttribute : TypeFilterAttribute
{
public ApiAuthorizeAttribute(string[] origins) : base(typeof(ApiAuthorizeFilter))
{
Arguments = new object[] { origins };
}
}
public class ApiAuthorizeFilter : IAuthorizationFilter
{
readonly string[] _origins;
public ApiAuthorizeFilter(string[] origins)
{
_origins = origins;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
if (_origins == null)
return;
string referer = context.HttpContext.Request.Headers["Referer"].ToString();
if (string.IsNullOrWhiteSpace(referer) || !_origins.Any(origin => referer.StartsWith(origin, StringComparison.OrdinalIgnoreCase)))
context.Result = new ForbidResult();
}
}
Things to consider:
The implementation and check of the referer could be exact match instead of StartsWith
The handling could use RegEx or any good alternative to handle subdomains, wildcards etc
The referer could be translated to a Uri objects to get better results and variations
A jQuery ajax call gets a "403 - Forbidden" as expected, but Postman gets a "404 - Not Found". To me that does not matter, but that's something to look into if it matters.
But it covers what I need, so I'm happy with this.
I receive request via a router :
#Bean
public RouterFunction<ServerResponse> routerFunction() {
return nest(path(API_PATH), route(GET("/"), indexHandler::getIndex));
}
handle by a method :
public Mono<ServerResponse> getIndex(ServerRequest request) {
...
}
I need to extract the url use to request the service, I have different cases, sometimes request are direct to service, sometimes request go through proxy (and add X-Forwarded-Path,X-Forwarded-Path headers).
Is there a helper method, to extract this details from ServerRequest object ?
I have legacy web application built using apache Tapestry. I have deprecated most of the application's functionality except few pages. I want this application to be running in production, but I want to redirect deprecated pages/URLs to some error page with 404 error code. Where should I configure it? I have web.xml and jboss-web.xml. Do I need to do it in some Tapestry configuration file?
You can contribute a RequestFilter to the RequestHandler service, i.e. in your AppModule:
public void contributeRequestHandler(
OrderedConfiguration<RequestFilter> configuration)
{
// Each contribution to an ordered configuration has a name,
// When necessary, you may set constraints to precisely control
// the invocation order of the contributed filter within the pipeline.
configuration.add("DeprecatedURLs", new RequestFilter() {
#Override
public boolean service(Request request,
Response response,
RequestHandler handler) throws IOException
{
String path = request.getPath();
if (isDeprecated(path))
{
response.sendError(404, "Not found");
return;
}
return handler.service(request, response);
}
}, "before:*");
}
Notice the before:* ordering constraint, it should register this filter as the first in RequestHandler's configuration.
I have a spring data REST application in which I have added a interceptor for authentication & authorization.
private static final boolean IS_JPA_AVAILABLE = ClassUtils.isPresent("javax.persistence.EntityManager",
RepositoryRestMvcConfiguration.class.getClassLoader());
#Override
public JpaHelper jpaHelper() {
if (IS_JPA_AVAILABLE) {
JpaHelper helper = new JpaHelper();
helper.getInterceptors().add(new MyInterceptor());
return helper;
} else {
return null;
}
}
In this application, I have few controllers as well. Some of them are #RepositoryRestController & other are #BasePathAwareController. I want to call the interceptor when a request comes to these controllers. For #RepositoryRestController the interceptor get called, but for #BasePathAwareController it is bypassed.
How can I make this interceptor get called for both controller classes?
This issue is resolved by adding mapped interceptor (thanks llya for your inputs). In the configuration class, I have added following mapped interceptor. In this way it will be called for all requests coming to any controller.
#Bean
public MappedInterceptor myMappedInterceptor() {
return new MappedInterceptor(new String[]{"/**"}, getSecurityInterceptor());
}
Reference
How to add Custom Interceptor in Spring data rest (spring-data-rest-webmvc 2.3.0)