Spring: Global Path Variable or Request Parameter without Controller - spring

I have a Spring Boot & Spring Security application running, which should now get multi tenancy support.
I'd like to keep things as simple as possible. Though I'd like to determine the the database by path variable or request parameter. (the Apache Web Server in front of the Spring Boot app will handle that, i.e. it maps from subdomain to either path variable or request parameter).
Now I need a way to grab the first path variable (or a specific request param) before Spring calls the controller, and of course the value must be stored somewhere, so I can access it when I need to choose the right database.
So either (depending on what's possible / easier)
http://localhost:8080/customer1 (which I'd prefer) or
http://localhost:8080?_customer=customer1
should simply call the #Controller with #RequestMapping("") and the value customer1 should be stored somewhere for that request.
I know that 2. might be simpler, because it will already hit the right #Controller, but I'd prefer 1. somehow.
Thank you!
EDIT:
I just recognized, that HandlerInterceptor doesn't work as expected, because Spring Security always handles the requests first. Though I need an Interceptor that handles it before Spring Security kicks in.

You can make use of org.springframework.web.servlet.HandlerInterceptor. Implement the logic to store the values in request via preHandle method.
Configure it in spring config file as below
<mvc:interceptors>
<bean class="com.blah.interceptor.SomeInterceptor"/>
</mvc:interceptors>
In case requests are to be intercepted based on path, use below config instead
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/customer1" />
<bean class="com.blah.interceptor.SomeInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

Related

How to make relative redirect to Authorization Endpoint in Spring OAuth?

I configured a service with oauth2Login.
User is redirected to Authorization Endpoint - /oauth2/authorization/{registrationId} when he/she is not authorized.
I would like to customize redirection in a way that it takes into account path prefix, since application is accessible trough prefix /api/myapp/.
From the source code I can see that there is OAuth2AuthorizationRequestRedirectWebFilter during Spring Security setup and this filter is using DefaultServerRedirectStrategy which decides if location is relative or not. Moreover it uses a contextPath which is hard to set when using Spring Boot.
Unfortunately I don't know how to override default behavior to make redirect relative.
I don't need to modify contextPath. Instead I've registered ForwardedHeaderTransformer as a bean.
This transformer is able to retrieve headers set by proxy (X-Forwarded-Prefix) and sets context path for request correctly.

For validating session attribute, which is better in spring - Interceptor or Spring AOP?

In my application, after a user is logged in, every time he sends a request (get/post), before calling the method in controller, i want to verify the session attribute set in the request (i set a session attribute during his login). I see that this can be implemented through spring interceptors (OR) spring AOP. which one should i use?. I have a feeling interceptors are outdated. Or is there a way in spring security which does this for me?
So you want this intercept to happen only for all the controller methods ..? Does the controller have Base URL that its getting invoked for (post/get/delete)...? Is it more like you want to intercept the http request for a particualt URL ..? like this one
<intercept-url pattern="/styles/**" filters=" .." />
If your use case is boiled down to a particular URL pattern then you can write a custom filter extending GenericFilterBean and you can plug it to the filters attribute.So this will get called for every request matching url pattern and in your custom filter you can do whatever you wanted to do.
What if you try implementing a simple Filter? You can extend already existing Spring filter, or create your own by implementing javax.servlet.Filter
The spring security way seems the best way to me with access to specific roles also can be assigned. very good example given in http://www.mkyong.com/spring-security/spring-security-form-login-using-database/

Spring customised PropertyPlaceholderConfigurer

I have config xml based spring application for which I have moved proprties required at start up time in database. It was very difficult to manage hundreds in property file and that is why database is introduced. To read properties a spring restful service is developed to return a map of all properties required at start up time.
I want to know how to replace properties reading from a map to spring context file e.g. ${config.service.url} should be polulated from a map read via web service.
One option I considered is to upgrade to Annotation based and start using MapPropertySource and Environment interface as environment.getRequiredProperty("config.service.url"). However upgrading to Annotation based is a big impact on project and is no at this time.
Second option that I am looking forward is to have a customised PropertyPlaceholderConfigurer.
Any pointer/help on this will be great.
Cheers,
Amber
You could define a PropertyPlaceholderConfigurer, but instead of specifying a file location, you can pass the properties directly as returned by your restful service.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" .../>
</bean>

Camel Route setup for testing based on static property value

I am trying to introduce Unit testing in the interface layer.In code we provide <from:sedaQueueName> and camel parses the message and send it to external systems.
I want to change the route <to:ExternalSystem> to <to:PrintMessageOnScreen>.
I am already using a static global value isUnitTest to get database connection outside the container.
Is there a way I can use the same variable value in application Context to decide my route?
I can access the property value using Spring SL like this:
<bean id="forTesting" class="test.UnitTest">
<property name="isUnitTest">
<value>#{T(test.UnitTest).isUnitTest}</value>
</property>
</bean>
I am not sure how to read this property inside a camel route and decide my route based on its value.
you can use the dynamic router just check the documentation, or you can use the content based router here its documentation

Spring Security: how to make listener for opening any page by user?

I need to handle user's request any time when he trying to load some page. At this listener i need to make some special checks, and, in result, close or not close user's session. How i should implement this? Looks like a common task, but i'm pretty new to spring and spring security.
I think of a listener as something that observes behaviour but doesn't affect behaviour. Since you mention closing the user's session, this is definitely affecting the user. Therefore, I think you are talking about an interceptor/filter rather than listener.
Spring provides a good interceptor framework for something like this.
However, since you are talking about sessions, this is the domain of spring security. Looks like there is another way to handle session management here: Is it possible to invalidate a spring security session?
Like Lithium said, a filter would supposedly be appropiate to handle the given task. Spring Security uses it's own filter chain (link points to 3.1.x docs), to which you can add your own filters - be careful about the positioning of your filter in the chain, here are some notes on ordering.
Depending on your requirements, such a filter could for example redirect the user to another page than the requested one one stop executing the filter chain - again: positioning in the filter chain is vital.
I think you should try interceptor. Little more details:
Create HandlerInterceptor class
public class RequestInitializeInterceptor implements HandlerInterceptor {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//Code to perform database checks
}
}
Define interceptor in servlet-context.xml (ApplicationContext for Servlet) file
<mvc:interceptors>
<mvc:interceptor>
<!-- Update path as per you requirement --!>
<mvc:mapping path="/**"/>
<bean class="com.abc.web.support.RequestInitializeInterceptor" />
</mvc:interceptor>
</mvc:interceptors>

Resources