Springboot security access per field - spring

I would like to make access per field in spring mvc.
For example
I got entity with 3 fields
id,name,description.
User with ROLE_USER can see only name and user who got ROLE_ADMIN can see name and description. I tried to use
#PreAuthorize("hasRole('ROLE_USER')") in entity and dto but its only work in service and controller.
I tried to use #Component adonation before #Entity but it doesnt work.
ps: prePostEnabled is configured
#EnableGlobalMethodSecurity(prePostEnabled = true)
any solutions?

For this propouse a better approach is use the spring security tag if you are using jsp or thymeleaf spring security dialect if you are using thymeleaf.
in the first case you have this maven dependency in your pom
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>your.version</version>
</dependency>
in the second case you have this maven dependency in your pom
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>your.version</version>
</dependency>
the key point hear is that with #EnableGlobalMethodSecurity you are working at method security protection and not at presentation level protection. In other words with your configuration you can protect the your method calling at application level in base of how the Security contect is popolated while for a presentation protection Spring security provide some custom tag for acive this propouse, for thymeleaf you can use the security dialect.
I hope that this can help you

Related

How to inject a bean into JAX RS resource?

I am sure this is most probably a silly question but I am not familiar with JAX RS (and Jersey).
We've had a standalone Java application that basically starts a RESTful service. As part of a refactoring, we've moved this application to be just a thread within another application. That other application uses Spring beans that are defined in an application-context.xml. So, I need to inject some of those beans to the resource class (if that's the correct name for it: the one with #Path annotations, etc.). The problem is I don't know what instantiates this particular class. There is a main class of the legacy app that is creating a (jetty) Server instance with ServletContexthandler to which a ServletHolder is added to which a ResourceConfig is set. Something like that.
So, I can inject my stuff from Spring to this main class but can't see how exactly I can pass those objects to the JAX RS resource?
I am sure I miss something pretty simple.
Edit: I have added a better explanation to my problem and a solution I found below.
Jersey has integration with Spring support. For this case, there are really only two things you need to do:
Make sure you have the integration dependency. You'll also need to the commons logging, so it doesn't complain
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring4</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
Just add a ContextLoaderListener along with a WebApplicationContext containing your Spring context configuration.
ServletContextHandler context
= new ServletContextHandler(ServletContextHandler.SESSIONS);
AnnotationConfigWebApplicationContext wac
= new AnnotationConfigWebApplicationContext();
wac.register(SpringConfig.class);
context.addEventListener(new ContextLoaderListener(wac));
Here the SpringConfig is just a "Java config" Spring configuration class. If you wanted you could use an XML application context, but the example I used in the below link uses a Java config class, but also show how to easily import an XML into the class if you just want to use your XML config. You can combine two.
That's pretty much it. Once you have this configured, you should be able to #Autowired your Spring beans into your Jersey resources.
For a complete example, check out this GitHub repo
Maybe I wasn't able to explain well my problem, so basically it was a problem of how to inject beans into JAX-RS resource classes when the actual JAX-RS app is not being instantiated through its own DI-mechanism but from somewhere else. In my case I already had a Spring container that creates those beans and there was no easy way to link the Spring's own bean application context to the JAX-RS's one. A better solution would have been the one already answered but additional problem is that our existing Spring solution is XML-based, whereas the #Injected annotation in JAX-RS won't work with it (at least that's what I've read in their documentation).
So, JAX-RS supports #Injected annotations and in order for it to know where to get bean definitions from, I had to go to the class that defines the ResourceConfig and add the following lines to it:
.register(new AbstractBinder() {
#Override
protected void configure() {
bind(beanImpl1).to(BeanInterface1.class);
bind(beanImpl2).to(BeanInterface2.class);
}
})
The actual beanImpl1 and beanImpl2 bean instances were coming through the constructor of that class, which in turn was instantiated from our Spring through the XML configuration.

Prevent XXE (External Entity Processing) Attack with JAXB + Spring RESTful Web Services

I know that we can prevent the XXE attack by setting the property IS_SUPPORTING_EXTERNAL_ENTITIES in the abstract class XMLInputFactory to false in JAXB.
I have also seen this stackoverflow answer.
My question here is,
How do I create a instance of XMLInputFactory and set this IS_SUPPORTING_EXTERNAL_ENTITIES property to false when the spring application loads up. And that particular XMLInputFactory instance should only be used for all the JAXB conversion for all the classes that uses javax.xml.bind.annotation package.
Spring uses RequestMappingHandlerAdapter which is an AbstractHandlerMethodAdapter that supports HandlerMethods with the signature -- method argument and return types, defined in #RequestMapping.
There are 7 seven HttpMessageConverters and one of them is Jaxb2RootElementHttpMessageConverter
Jaxb2RootElementHttpMessageConverter is from the spring-web package.
From 3.2.8 version of spring-web onwards Jaxb2RootElementHttpMessageConverter sets the processExternalEntities to false which in turn sets the XMLInputFactory property IS_SUPPORTING_EXTERNAL_ENTITIES to false.
Refer : Jaxb2RootElementHttpMessageConverter from Spring
Answer use
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>

Why doesn't Spring 3.1 automatically use Jackson when POST header Content-Type=application/json?

No configuration or annotation is needed when setting request header "Accept=application/json"
It's almost automatic. Referring to
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-config-enable
Jackson is automatically selected and registered when it is in the classpath (i.e. pom.xml) and you use mvc:annotation-driven in your context config.
It does work automatically - in my controller I used an incorrect annotation - I used #RequestParam - it must be #RequestBody
In my situation, I fixed it with using another source for Jackson, because #RequestBody does not converted to the type I expect.
Instead of Codehause Jackson, I use now fasterxml:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.3</version>
</dependency>

Spring annotation in Controller don't work? None of #Secure and #Async works

I use spring-roo to generate my project. I don't know these 2 things are related or not, but in Controller, none of the annotation #Async or #Secure works.
For #Secure:
I added <global-method-security secured-annotations="enabled"/> tag to applicationContext-security.xml and modified the pom.xml to meet dependency,
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-aspects</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
above the method in the controller, I added #Secured("ROLE_ADMIN") but no matter what role everybody can access the method. Anything I missed to configure to make the #Secure Active?
For #Async:
In applicationContext.xml, I added
<task:annotation-driven executor="asyncExecutor"/>
<task:executor id="asyncExecutor" pool-size="${executor.poolSize}"/>
in controller.java:
#Async
private void justWait20seconds() {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I expect this method will not block the main method, but it didn't. These 2 tag are all in my UserController.java, I don't know whether they are linked. Can anyone help?
It sounds like you don't understand how Spring contexts are organized in a Spring MVC application and are adding the annotation processing instructions to the wrong context. Do some reading on Spring contexts in Spring MVC. You can find another SO answer of mine that branches to other related answers at: Why DispatcherServlet creates another application context?
I had the same problem in which security annotations worked in a Roo project's jspx's but not in the controllers. My fix was to add the following to webmvc-config.xml:
<security:global-method-security secured-annotations="enabled" />
(adding this to applicationContext-security.xml did NOT work for me)
Then I added dependency for cglib in the pom.xml:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>

Spring MVC: Adding JAXB to the classpath so that it automatically serializes XML

According to Spring MVC documentation, <mvc:annotation-driven/> configures support for JSON if Jackson is in the classpath, and support for XML if JAXB is present in the classpath. Simply by adding a Jackson dependency to my pom.xml, I get JSON support to work! (see: Ajax Simplification in Spring 3.0)
However, after trying to access the same service with accept header "application/xml", I get a 406 Not Acceptable response. What's the simplest way to get JAXB in the classpath? What is necessary to enable support for XML MarshallingHttpMessageConverter?
Update
Taking a look at AnnotationDrivenBeanDefinitionParser, I can see what defines if "jaxb2Present". I set a breakpoint around line 179 to see if the Jaxb2RootElementHttpMessageConverter is indeed being registered like the MappingJacksonHttpMessageConverter is. It isn't...
What's the simplest way to add JAXB to the classpath to make it automatically serialize my XML requests?
It should work. Make sure that the object being returned has #XmlRootElement annotation as required by JAXB.
If you're using Java 6, JAXB is already on the classpath. If you're using Java 5, you'll need to add a reference implementation yourself.
If you're using Maven, you can add to your pom.xml:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2</version>
</dependency>

Resources