Spring MVC: Domain restriction for a single controller - java

I know that we can use Spring security to restrict access to a controller by IP address or even I can create my custom annotation to add some custom logic for this purpose.
I need to restrict access to a controller in my application to only specific domain name ( a third party ), I checked with this third party provider for the IP ranges which I can use to configure at my end, however they want to have more freedom around IP address and would like me to create access based on the domain name.
I checked through the doc but unable to find any such use cases, Can any one help me to understand if this is possible or I need to go back to IP based access mechanism ?

i think you can use Spring's CORS support for this.
ie if the domain that you expect the request is example.com you can have in your controller method the following annotation
#CrossOrigin(origins = "http://example.com")
This #CrossOrigin annotation enables cross-origin requests only for
this specific method. By default, its allows all origins, all headers,
the HTTP methods specified in the #RequestMapping annotation and a
maxAge of 30 minutes is used. You can customize this behavior by
specifying the value of one of the annotation attributes: origins,
methods, allowedHeaders, exposedHeaders, allowCredentials or maxAge.
In this example, we only allow http://localhost:8080 to send
cross-origin requests.
Have a look in the following url https://spring.io/guides/gs/rest-service-cors/

Related

How to add matchOnUriPrefix on existing Camel Jetty REST routes?

We have existing REST routes working with Camel 2.23.1 and jetty. We redirect incoming calls to an appropriate server based on the uri, query, and the user's authentication. We want to handle this more generally.
How can we modify the following code to handle any uri with "/say" as the prefix?
In our RouteBuilder:
RestConfigurationDefinition rConfig = restConfiguration()
.component("jetty")
.port(webserverPort)
.contextPath("/")
.bindingMode(RestBindingMode.off)
.enableCORS(true)
.dataFormatProperty("prettyPrint", "true");
rest("/say")
.get().to("direct:test");
from("direct:test")
.bean(RouteRest.class, "getTestURI(*,*)")
.to("mock:output");
We have tried adding a property to the restConfiguration, ala
.componentProperty("matchOnUriPrefix", "true");
We have tried adding the same property to the rest route definition, ala
rest("/bye?matchOnUriPrefix=true")
We have tried creating a new from statement, which seems to break everything, ala
from("jetty://0.0.0.0:8123/now?matchOnUriPrefix=true").to("direct:test");
I am aware of this question and answer, but don't know how to apply it to my case:
stackoverflow.com/questions/39341784
Further, is it possible to match some incoming calls with explicitly defined uri's, like "/admin/status", and all other uri's to "direct:test"?
We ended up taking out the restConfiguration() entirely and configuring endpoints individually, which fit our expanding requirements anyway. Our oritinal restConfiguration() was limiting the messages that could get to the endpoints themselves. Perhaps we could have modified the restConfiguration directly to enable greater flexibility, including removal of .contextPath("/"). This directly allowed the following code to work:
from("jetty:http://{{ip}}:{{port}}?matchOnUriPrefix=true")
.bean(RestForward.class, "checkUserAuth(*)")
.bean(RestForward.class, "checkDevice(*)")
.bean(RestForward.class, "forward(*,*)")
.to("mock:output");

Spring Data Rest: how to transform all urls in Kebab Case?

I want to use spring-data-rest to expose my repositories via an API. URLs are generated from domains name. Those URLs are camelized.
For example, considering domain named EntityA, the associated url and rel will be entityA (in camelCase).
How can I configure spring-data-rest (or what have I to override) to get kebab-case by default ? (for example, entity-a instead of entityA)
I know that I can use #RestRepository and provide URLs for each repositories. But I'm looking for better solution. I want to use kebak-case for entities and searches methods.

Can you specify preferred default media type for a single path in Spring MVC?

I have a Jersey application which has been converted to Spring MVC. One piece of functionality that I don't see a way to port directly over is the ability, per path, to specify the preferred media type if none is specified. In Jersey, I could specify the "qs" property on the media type, and it would use that to determine which response type to send if none were specified (or if multiple options were specified in the Accept header, I believe this value was multiplied by the quality scores specified).
#Produces("application/json")
#GET
#Path("/some/path")
public Response preferredResponseType() {
//Implementation goes here
}
#Produces({"application/schema+json;qs=0.9"})
#GET
#Path("/some/path")
public Response otherResponseType() {
//Implementation goes here
}
In this example, if I do a GET request against /some/path with no Accept header, it will return the application/json response.
I don't see any easy way to do this in Spring MVC, particularly not if I want to restrict the default to applying to just that one endpoint (there are other endpoints in the app that should have a different preferred default). I do see that there is a way to globally set a default content type (per the "defaultContentType" and "defaultContentTypeStrategy" methods in ContentNegotiationConfigurer), but that does not easily address the per-path use case.
Is there an easy way to achieve per-path media type defaults different from the application global default?
Spring issue 19050 requests this functionality. Per the conversation there, it looks like there is no simple way to declaratively specify the default content type to use. Furthermore, the Spring team has closed the issue with a decision not to implement this functionality.
The "defaultContentTypeStrategy" allows to provide your own ContentNegotiationStrategy to use. It has access to the full request so you can make path based decisions possibly with the an AntPathMatcher to support patterns easily.

Play framework route parameter authorization

I have REST api on my page and for authentication I use the Play session.
Problem is with authorization, I have tens of endpoints looking like this:
GET /api/domains/:domainId/properties/:propertyId/reports
I could add and if statement on each controller method to check whether user has permissions to that domain or property, but can I handle it somehow globally?
I found this module, but it does not seem to handle parameters, just checks if user is in some group/role or not. https://www.playframework.com/documentation/1.0.2.1/secure
I solved this using a custom RequestHandler. There you can extract parameters from the path and validate them. (In scala I could even modify the request route in order to avoid repeating these parameters in all routes, I don't know if you can do it in java too).
(See:
https://www.playframework.com/documentation/2.4.x/JavaHttpRequestHandlers)
You can use the Security.Authenticated annotation as detailed here. For more specific permissions, I recommend Deadbolt

Authentication in multiple methods with JAX-RS/Jersey - How to keep it clean?

I'm working on a web service written in Java using JAX-RS/Jersey and Spring.
The WS authenticates a user when he or she logs in and returns an access key which has a limited lifespan. Most of the available methods require a valid "access key + userId" combination.
For all of the available methods I am using #FormParam to retrieve POST parameters, and the response is in JSON. What I am trying to figure out is how to avoid having to type out
#FormParam("userId") final Integer userId,
#FormParam("accessKey") final String accessKey
and manually invoke my authentication method for each of the probably 20 methods I will have that require authentication. This is especially cumbersome because I will then also have to add code to handle e.g. expired access keys.
Is there another way to go about retrieving the two parameters above and performing authentication so I can keep my methods clean?
Since you're using Jersey, you can use servlet-filter-like APIs to DRY up your code. Check out:
Equivalent of Servlet Filter for Jersey / JAX-RS / REST resources?
How does one intercept a request during the Jersey lifecycle?
ContainerRequestFilter

Categories

Resources