Register Spring filter from BeanDefinitionParser - spring

I am creating a custom namespace for use in the Spring XML configuration. I already implemented a NamespaceHandler and BeanDefinitionParser. So, now I can just put <myns:some-awesome-feature /> into my Spring configuration and it creates the required beans automatically.
In addition to creating some normal Spring beans I would also like to have this annotation register a OncePerRequestFilter to extract some information off of a request for my code to be able to utilize. Is there a way to register a filter programmatically using the two classes I have available when implementing a custom XML tag?

It is not possible without touching web.xml or WebApplicationInitializer, respectively.
But you can create an extendable solution that allows modifications in future without hassle.
Spring Security's <http pattern='...' security="..."/> automatically creates and registers a series of chained filter beans for you. All you have to do is to
register DelegatingFilterProxy in you web.xml and reference springSecurityFilterChain.
You can create a similar solution where you are defining e.g. <myns:awesome-http pattern='...' /> which instantiates OncePerRequestFilter. In web.xml you are declaring a DelegatingFilterProxy which references your awesomeFilterChain. In a future version you can add more filter to your chain without touching the configuration.
I have never implemented such a feature but I'm quite confident that it is possible.
As a starting point take a look at the source of HttpConfigurationBuilder and HttpSecurityBeanDefinitionParser to see how Spring Security implemented <http .../>.

Related

duplication in parsing spring context

Nowadays I've got to know spring mvc.
exactly about
context:component-scan
and
mvc:annotation-driven
and
tx:annotation-driven
in spring config xml
Here is my question.
As I know, "context:component-scan" scans all beans.
and As I heard, mvc:annotation-driven, tx:annotation-driven"s also scan all beans.
I think this is not efficient and not reasonable.
Why scan twice, three times.
Is there any way to avoid this duicate parsing?
Any answer will be appreciated.
Thank you.
In my opinion, scanning process are not twice, three times as you think.
They are declare for related beans I think.
Please refer to below summarize and find out how differences.
<context:annotation-config>
Declares support for general annotations such as #Required, #Autowired, #PostConstruct, and so on.
<context:component-scan>
can also do what <context:annotation-config> does but <context:component-scan> also scans packages to find and register beans within the application context.
<mvc:annotation-driven />
Enables the Spring MVC #Controller programming model and
declares explicit support for annotation-driven MVC controllers (i.e. #RequestMapping, #Controller, although support for those is the default behaviour), as well as adding support for declrative validation via #Valid and message body marshalling with #RequestBody/ResponseBody.
<tx:annotation-driven />
You do provide the transaction-manager instace directly within element. annotation-config and component-scan won't.

Using Spring for DI with Annotations in a Portlet without using DisplatcherPortlet

I have a huge set of really old Portlets code I am being required to "refactor" due to a bug that was found in Prod. The refactor is requiring me to update to a new library, and as a result move from a custom DAO structure using "Query" classes to one that uses Springs JdbcTemplate and annotations to wire everything together.
BUT, there are a LOT of portlets. Is there a way to use Spring with Annotations for DI that does NOT require me to completely re-write the Portlet to use DispatcherPortlet and the #RequestMappings? I just want to mark all the Portlets, and the handful of Servlets as well, with #Component just to have Spring inject the classes I need. Where I am struggling is in how to bootstrap the ApplicationContext without using the Spring-provided dispatcher portlet/servlet to initiate the context. I would like to not have to use the ApplicationContext directly to pull the necessary beans out by hand, if possible. I do have contextConfigLocation and the ContextLoaderListener defined in my web.xml already.

How can I include/exclude certain controllers from a DispatcherServlet

I have a DispatcherServlet which by default uses a RequestMappingHandlerMapping to find all controllers with #RequestMapping annotations.
This works fine, except that it picks up all controllers in my spring context, but I only want it to expose certain controllers.
Is there any way of doing this that doesn't involve extending a bunch of spring classes?
(Unfortunately my spring context has to contain these additional controllers as they also provide some functionality that I need to call using java, and I'm not able to split these up currently)
You can configure include/exclude filters to customize classpath scanning. This can be done both in XML Spring config or Java based #Configuration. So depending on how many #Controller annotated classes you need to exclude, you can either list them under assignable or use regex filter. See Spring docs section "Using filters to customize scanning" for details, e.g. for Spring 3.2.

What is good practice to configure Spring MVC application with Spring security?

Assume I have Spring MVC powered application with Spring security. I have:
UserBean class which provides CRUD operations on table User
UserController : controller which expose operation on User to http clients
UserLogin: Authentication provider from Spring security, which authenticates users.
How should I configure my application if:
I want simple XML configuration, with auto-discovering beans by annotations (<context:component-scan base-package="org.example"/>)
UserLogin and UserController needs UserBean to work
UserLogin and UserController use transaction annotations and aspect annotations
I see the following oportunities:
Create one common Spring XML configuration file, used both by DispatcherServlet and ContextLoaderListener
Disadvantage: nobody shows that solution in tutorial. All beans are duplicated (one instance in ContextLoaderListener context, second in DispatcherServlet). Duplication may cause some hard to track bugs. Duplication is not elegant
Create two Spring XML configuration files, one for ContextLoaderListener (main) and one for DispatcherServlet (controllers). UserBean is declared in first config and visible in second one
Disadvantage: to avoid duplication I have to add complex component scanning rules to both files (context:component-scan). <tx:annotation-driven and <aop:aspectj-autoproxy/> must be defined in both files. I will have still doubts which config file is appropiate when declaring new stuff.
Create two Spring XML configuration files and include third for common settings like <tx:annotation-driven
Disadvantage: I wanted simple solution...
Summary: I'm looking for good practice to configure application with Spring MVC + Spring Security AND security part is highly connected with business part. I was searching for good example but I always find case when security code is isolated from business code. But I need example when security and business share the code
Similar question: ContextLoaderListener or not?
I have two xml files for my configuration, no particular reason, that's just how it worked out.
These sample spring security projects provide good examples of lots of different types of configurations maybe you can find something that works for you:
https://github.com/spring-projects/spring-security/tree/master/samples
Hidden message in my question was: having two contexts is stupid.
Did someone already notice that?
Is there a way to have single application configuration?
Answers:
Yes. https://jira.springsource.org/browse/SPR-6903
Yes. https://github.com/michaldo/spring-single-context-demo
The best practice which applies to my case is described here: https://stackoverflow.com/a/14032213/2365727

Hard?: Spring security on classes that are not Spring Beans?

Definitely need some expert help with this! I think this is mainly a Spring Security question, but as I don't know for sure, so I am also tagging with the general Spring tag!
When the Application Context is loaded (mine is all via Java Config, though I don't believe that matters), the "DefaultListableBeanFactory" is processed and eventually (via the ProxyFactory) Spring Security Advisors are added. This is great when I have Spring Beans as I have Permissions that need authorization.
My question is: how do I get the same effect when I no longer require those classes to be Spring Beans? Said differently, if I have an object instance created as a singleton bean via Java Config and the authorization is working correctly, is it possible to maintain that with the object instance being a POJO? Again, for the experts, I want the interception chain returned in the JdkDynamicAopProxy to contain the Spring Security interceptors.
And "no", I am not really expecting an answer to this, maybe just hoping!!!
To add security interceptors to beans not instantiated by spring container
switch global-security tag to mode aspectj and weave the provided AnnotationSecurityAspect in the aspecj module.
For your second question I suppose that you want to do one of the following:
Use a ProxyFactoryBean to secure a bean.
Create security proxies programmatically: Use ProxyFactory.addAdvice() method.
Add the security interceptor to all proxies created by an AutoProxyCreator: This usually don't needed, but you can use the AbstractAutoProxyCreator.interceptorNames property to add common interceptors. The global-security tag parser uses a generated name for the MethodSecurityInterceptor, so you need to configure the interceptor manually and set a consistent SecurityMetadataSource.

Resources