This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

AnnouncementAnnouncement Module

Collapse

No announcement yet.

Two <http> container elements with one for the browser and one for RESTPage Title Module

Now, I'm adding some REST request controller and I would like to have a slightly different behavior of its authentication, that is, a successful authentication should not do a redirect but simply return a 200 OK response and a failed authentication should not do a redirect either but simply return a 401 UNAUTHORIZED response.

Comment

Each <http> element is considered in order so make sure that you list the /admin/json/** first. Otherwise the form based login matches everything (this means that the /admin/json/** one will never be reached).

Comment

Do you really intend to use form-login for your admin URLs? This is going to redirect you to a login page. The http-basic@entry-point-ref is only used for a failed basic authentication, not prompting for credentials when none are present. I'd remove form-login and add http@entry-point-ref="restAuthenticationEntryPoint".

Comment

I think you are going to need to use DelegatingAuthenticationEntryPoint and assign it to http@entry-point-ref. This will allow Spring Security to use one entry point for your REST requests and another for your HTML requests. You will need to create a RequestMatcher instance that matches your REST requests (i.e. perhaps it looks at the content type). If it matches, you will delegate to the restAuthenticationEntryPoint. If it does not match, then you will delegate to a LoginUrlAuthenticationEntryPoint. Of course you can switch the logic and have a RequestMatcher that finds HTML requests and delegate to LoginUrlAuthenticationEntryPoint, else delegate to restAuthenticationEntryPoint. See the javadoc of DelegatingAuthenticationEntryPoint for an example of configuring it.

Comment

No you should not need to abandon the XML configuration. I'm a big lost as to what your configuration looks like now, but taking the previous post as an example you would do something like this:

Code:

<http use-expressions="true" pattern="/admin/json/**" entry-point-ref="entryPoint">
<intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
<http-basic entry-point-ref="restAuthenticationEntryPoint" />
<!-- if you want this http element to authenticate (and thus use its success handler) you need to have login-processing-url match the pattern on http (i.e. start with /admin/json) -->
<form-login authentication-success-handler-ref="restSuccessHandler" login-processing-url="/admin/json/authenticate"/>
<logout />
</http>
<b:bean id="entryPoint" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
<b:constructor-arg>
<b:map>
<!-- this is creating a ELRequestMatcher , you could also do a custom RequestMatcher implementation which would be more powerful -->
<b:entry key="hasHeader('Accept','application/json')" value-ref="restAuthenticationEntryPoint" />
<!-- alternative to the above entry which is more powerful You need to create a bean named restRequestMatcher that implements RequestMatcher and returns true when it is a rest request -->
<b:entry key-ref="restRequestMatcher" value-ref="restAuthenticationEntryPoint" />
</b:map>
</b:constructor-arg>
<b:property name="defaultEntryPoint" ref="formLoginEntryPoint"/>
</b:bean>
<b:bean id="formLoginEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<!-- keep in mind the form must submit the the http element that you want to process it. This means you will want it to submit to a URL that starts with /admin/json/authenticate for this example -->
<b:property name="loginFormUrl" value="/login.jsp"/>
</b:bean>

* Thinks of each <http> as a "slice" of your application that is considered in order. The slice is split up using http@pattern or http@request-matcher-ref.
* If a requset matches the <http> block no other <http> blocks are considered
* Each URL or pattern within the <http> block is independent of the http@pattern (merging these would be too complex especially when considering the request-matcher-ref can be anything). So for example if http@pattern="/admin/json/**" and intercept-url@pattern="/something", the intercept-url will never be matched. Likewise, if if http@pattern="/admin/json/**" and your form-login@login-processing-url="/j_spring_security_check" then it will never match and try to authenticate the user (form-login is never considered unless it matches http@pattern)