Rich
Rich

Reputation: 15464

Spring MVC 3 content negotiation restrict to actions which support it

I have configured content negotiation in my Spring MVC 3 app as follows:

        <bean
            class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
            <property name="order" value="0" />
            <property name="favorPathExtension" value="true" />
            <property name="defaultContentType">
                    <ref bean="htmlMediaType" />
            </property>
            <property name="mediaTypes">
                    <map>
                            <entry key="json" value="application/json" />
                            <entry key="xml" value="application/xml" />
                    </map>
            </property>
            <property name="defaultViews">
                    <list>
                            <bean
                                    class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                                    <property name="objectMapper" ref="jacksonObjectMapper" />
                            </bean>
                            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                                    <property name="marshaller">
                                            <bean class="org.springframework.oxm.castor.CastorMarshaller" />
                                    </property>
                            </bean>
                    </list>
            </property>
            <property name="viewResolvers">
                    <ref bean="tilesViewResolver" />
            </property>
    </bean>

This works very well -- all my views will render as html views with the 'normal' view templates, or as JSON or XML dumps of the view model data depending on the 'Accept' header.

However, this seems to be a bit of a security hole to me. Some of my actions are API-style actions, and are legitimately available in HTML or JSON or XML. However, some views are intended to be HTML-only. I don't really want end-users to be able to see all the view data just by adding ".json" to the url.

Is there any way to do content negotiation in Spring MVC, but only on actions which have explicitly opted-in to it? Can I set up a controller annotation like @RespondsTo("xml", "json")?

Upvotes: 2

Views: 548

Answers (3)

Rafał Wrzeszcz
Rafał Wrzeszcz

Reputation: 2067

I was just facing the same problem. produces attribute of @RequestMapping helps for that. Although it's the opposite of what you asked for - kind of opt-out instead of opt-in, but I think it's what can please you.

@Controller
@RequestMapping("/categories")
public class CategoriesController
{
    @RequestMapping(value = "/create", method = RequestMethod.GET, produces = "application/xhtml+xml")
    public String createForm(Model model)
    {
    }
}

/create - works fine by displaying JSP view /create.json - 406 Error

Upvotes: 1

Aravind A
Aravind A

Reputation: 9697

Why don't you use a filter through DelegatingFilterProxy to block users from accessing unnecessary content types ?

Upvotes: 1

cdeszaq
cdeszaq

Reputation: 31300

One way to do it would be to use Spring Security to restrict which pages can be seen based on the content-type (or whatever other method(s) you are using for content negotiation.

Upvotes: 0

Related Questions