You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by "Winnebeck, Jason" <Ja...@windstream.com> on 2013/10/28 22:02:58 UTC

Access to WADL disabled when enabling SecureAnnotationsInterceptor

I have enabled the SecureAnnotationsInterceptor to observe JSR-250 annotations on my service bean, and everything is working properly, except that it is no longer possible to view the WADL. I can view services page, WSDL, and all REST service URLs as expected but not ?_wadl page. Instead, the interceptor rejects the request with a "AccessDeniedException: Method is not available : Unauthorized" exception.

I'm using Spring security and its DelegatingFilterProxy to actually perform the authentication via HTTP basic.

When using this interceptor, how do I control access to the service listing, WSDL, and WADL?

Jason Winnebeck

----------------------------------------------------------------------
This email message and any attachments are for the sole use of the intended recipient(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message and any attachments.

Re: Access to WADL disabled when enabling SecureAnnotationsInterceptor

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Jason

FYI, this issue has been resolved,

https://issues.apache.org/jira/browse/CXF-5371

Cheers, Sergey
On 29/10/13 13:13, Sergey Beryozkin wrote:
> Hi,
> On 29/10/13 12:58, Winnebeck, Jason wrote:
>>> -----Original Message-----
>>> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
>>> Sent: Tuesday, October 29, 2013 8:09 AM
>>>
>>> SecureAnnotationsInterceptor is at the PRE_INVOKE stage, so I wonder
>>> how the call reaches it when WADL is requested, given that
>>> JAXRSInInterceptor which runs a WADL filter is at the earlier UNMARSHAL
>>> stage.
>>
>> I just debugged this. CXF 2.7.7 calls
>> AbstractAuthorizingInInterceptor, which calls getTargetMethod. It
>> finds that m.getExchange().get(BindingOperationInfo.class) and
>> m.get("org.apache.cxf.resource.method") return null. Because it cannot
>> perform its work it decides to be safe and throw access denied.
>>
>> In debugger I see that JAXRSInInterceptor's handleMessage is called
>> first. It finds a RequestProcessor, and calls its preprocess method,
>> which puts a Response onto the Message's exchange which has entity
>> with WADL content, which bypasses the rest of JAX-RS logic. Then
>> SecureAnnotationsInterceptor runs and throws from its handleMessage,
>> and it seems that this overrides the Response generated by
>> JAXRSInInterceptor.
>>
>> I created a class that extends SecureAnnotationsInterceptor, whose
>> handleMessage is below:
>>
>> void handleMessage(Message message) throws Fault {
>>    if (!"_wadl".equals(message.get(Message.QUERY_STRING))
>>      super.handleMessage(message)
>> }
>>
>> And now my service "works", but any user calling for example
>> /api/soap?_wadl can perform any SOAP operation. I could check for
>> "org.apache.cxf.rest.message" property, but I'd rather find a better
>> approach than risk making a security flaw.
>>
>> I should also note that my goal here is only to get CXF +
>> spring-security to work at all. SecureAnnotationsInterceptor was my
>> backup plan. I initially tried <sec:global-method-security
>> jsr250-annotations="enabled"/> in the beans XML, but this causes an
>> InternalServerErrorException thrown from at
>> org.apache.cxf.jaxrs.utils.InjectionUtils.reportServerError(InjectionUtils.java:457)
>> in cxf-rt-frontend-jaxrs-2.7.7 jar, the real cause is line 302
>> (injectThroughMethod), where it catches an exception because Spring
>> Security creates a proxy, and CXF has a reference to the Method from
>> the real class, and calling realMethod.invoke(proxy, ...) fails
>> because the proxy's class does not extend realMethod's class. This
>> might be due to a @Context method setUriInfo on the implementation
>> class rather than the interface. This method would probably be better
>> if possible, because I'd like to use an exception mapper, which
>> doesn't appear possible via the interceptor method.
>>
> Right, it is a fault that the in chain is not aborted immediately when
> Response becomes available as it interferes with the CXF interceptors
> which 'think' the invocation is still ahead. Will have to investigate.
>
> Please use
> http://svn.apache.org/repos/asf/cxf/tags/cxf-2.7.7/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/SimpleAuthorizingFilter.java
>
>
> on the JAX-RS path instead, it should resolve this issue
>
> Cheers, Sergey
>
>> Jason
>>
>> ----------------------------------------------------------------------
>> This email message and any attachments are for the sole use of the
>> intended recipient(s). Any unauthorized review, use, disclosure or
>> distribution is prohibited. If you are not the intended recipient,
>> please contact the sender by reply email and destroy all copies of the
>> original message and any attachments.
>>
>


Re: Access to WADL disabled when enabling SecureAnnotationsInterceptor

Posted by Sergey Beryozkin <sb...@gmail.com>.
On 29/10/13 13:49, Winnebeck, Jason wrote:
>> -----Original Message-----
>> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
>> Sent: Tuesday, October 29, 2013 9:14 AM
>>
>> Right, it is a fault that the in chain is not aborted immediately when
>> Response becomes available as it interferes with the CXF interceptors
>> which 'think' the invocation is still ahead. Will have to investigate.
>>
>> Please use
>> http://svn.apache.org/repos/asf/cxf/tags/cxf-
>> 2.7.7/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/Sim
>> pleAuthorizingFilter.java
>>
>> on the JAX-RS path instead, it should resolve this issue
>
> OK, I see how that would work, but there's no code to scan the JSR-250 annotations, but it wouldn't be wild to port SecureAnnotationsInterceptor logic over. However, I tried the original route using Spring Security and fixed. My issue is that I have interface MyService and beans in api project, then implementation project has class MyServiceImpl, which uses @Context. When Spring Security creates java.lang.reflect.Proxy, the which can't extend MyServiceImpl, and thus CXF JAX-RS cannot work with @Context fields and methods. The solution was to create an interface MyServiceContext extends MyService which has methods like @Context setUriInfo, then CXF will call through the interface, which works against the proxy. So I no longer need the interceptor approach. And since proxy throws exception from the calling method, I can use standard JAX-RS ExceptionMapper.
That filter is simply initialized with a reference to 
SecureAnnotationsInterceptor (or other authorizing interceptor), the 
latter will scan the annotations as expected.

Re contexts, you can create a standalone interface only, called say 
Injectable and have MyServiceImpl implementing both MyService & Injectable

Cheers, Sergey

>
> Jason
>
> ----------------------------------------------------------------------
> This email message and any attachments are for the sole use of the intended recipient(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message and any attachments.
>



RE: Access to WADL disabled when enabling SecureAnnotationsInterceptor

Posted by "Winnebeck, Jason" <Ja...@windstream.com>.
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: Tuesday, October 29, 2013 9:14 AM
>
> Right, it is a fault that the in chain is not aborted immediately when
> Response becomes available as it interferes with the CXF interceptors
> which 'think' the invocation is still ahead. Will have to investigate.
> 
> Please use
> http://svn.apache.org/repos/asf/cxf/tags/cxf-
> 2.7.7/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/Sim
> pleAuthorizingFilter.java
> 
> on the JAX-RS path instead, it should resolve this issue

OK, I see how that would work, but there's no code to scan the JSR-250 annotations, but it wouldn't be wild to port SecureAnnotationsInterceptor logic over. However, I tried the original route using Spring Security and fixed. My issue is that I have interface MyService and beans in api project, then implementation project has class MyServiceImpl, which uses @Context. When Spring Security creates java.lang.reflect.Proxy, the which can't extend MyServiceImpl, and thus CXF JAX-RS cannot work with @Context fields and methods. The solution was to create an interface MyServiceContext extends MyService which has methods like @Context setUriInfo, then CXF will call through the interface, which works against the proxy. So I no longer need the interceptor approach. And since proxy throws exception from the calling method, I can use standard JAX-RS ExceptionMapper.

Jason

----------------------------------------------------------------------
This email message and any attachments are for the sole use of the intended recipient(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message and any attachments.

Re: Access to WADL disabled when enabling SecureAnnotationsInterceptor

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi,
On 29/10/13 12:58, Winnebeck, Jason wrote:
>> -----Original Message-----
>> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
>> Sent: Tuesday, October 29, 2013 8:09 AM
>>
>> SecureAnnotationsInterceptor is at the PRE_INVOKE stage, so I wonder
>> how the call reaches it when WADL is requested, given that
>> JAXRSInInterceptor which runs a WADL filter is at the earlier UNMARSHAL
>> stage.
>
> I just debugged this. CXF 2.7.7 calls AbstractAuthorizingInInterceptor, which calls getTargetMethod. It finds that m.getExchange().get(BindingOperationInfo.class) and m.get("org.apache.cxf.resource.method") return null. Because it cannot perform its work it decides to be safe and throw access denied.
>
> In debugger I see that JAXRSInInterceptor's handleMessage is called first. It finds a RequestProcessor, and calls its preprocess method, which puts a Response onto the Message's exchange which has entity with WADL content, which bypasses the rest of JAX-RS logic. Then SecureAnnotationsInterceptor runs and throws from its handleMessage, and it seems that this overrides the Response generated by JAXRSInInterceptor.
>
> I created a class that extends SecureAnnotationsInterceptor, whose handleMessage is below:
>
> void handleMessage(Message message) throws Fault {
>    if (!"_wadl".equals(message.get(Message.QUERY_STRING))
>      super.handleMessage(message)
> }
>
> And now my service "works", but any user calling for example /api/soap?_wadl can perform any SOAP operation. I could check for "org.apache.cxf.rest.message" property, but I'd rather find a better approach than risk making a security flaw.
>
> I should also note that my goal here is only to get CXF + spring-security to work at all. SecureAnnotationsInterceptor was my backup plan. I initially tried <sec:global-method-security jsr250-annotations="enabled"/> in the beans XML, but this causes an InternalServerErrorException thrown from at org.apache.cxf.jaxrs.utils.InjectionUtils.reportServerError(InjectionUtils.java:457) in cxf-rt-frontend-jaxrs-2.7.7 jar, the real cause is line 302 (injectThroughMethod), where it catches an exception because Spring Security creates a proxy, and CXF has a reference to the Method from the real class, and calling realMethod.invoke(proxy, ...) fails because the proxy's class does not extend realMethod's class. This might be due to a @Context method setUriInfo on the implementation class rather than the interface. This method would probably be better if possible, because I'd like to use an exception mapper, which doesn't appear possible via the interceptor method.
>
Right, it is a fault that the in chain is not aborted immediately when 
Response becomes available as it interferes with the CXF interceptors 
which 'think' the invocation is still ahead. Will have to investigate.

Please use
http://svn.apache.org/repos/asf/cxf/tags/cxf-2.7.7/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/SimpleAuthorizingFilter.java

on the JAX-RS path instead, it should resolve this issue

Cheers, Sergey

> Jason
>
> ----------------------------------------------------------------------
> This email message and any attachments are for the sole use of the intended recipient(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message and any attachments.
>


RE: Access to WADL disabled when enabling SecureAnnotationsInterceptor

Posted by "Winnebeck, Jason" <Ja...@windstream.com>.
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: Tuesday, October 29, 2013 8:09 AM
>
> SecureAnnotationsInterceptor is at the PRE_INVOKE stage, so I wonder
> how the call reaches it when WADL is requested, given that
> JAXRSInInterceptor which runs a WADL filter is at the earlier UNMARSHAL
> stage.

I just debugged this. CXF 2.7.7 calls AbstractAuthorizingInInterceptor, which calls getTargetMethod. It finds that m.getExchange().get(BindingOperationInfo.class) and m.get("org.apache.cxf.resource.method") return null. Because it cannot perform its work it decides to be safe and throw access denied.

In debugger I see that JAXRSInInterceptor's handleMessage is called first. It finds a RequestProcessor, and calls its preprocess method, which puts a Response onto the Message's exchange which has entity with WADL content, which bypasses the rest of JAX-RS logic. Then SecureAnnotationsInterceptor runs and throws from its handleMessage, and it seems that this overrides the Response generated by JAXRSInInterceptor.

I created a class that extends SecureAnnotationsInterceptor, whose handleMessage is below:

void handleMessage(Message message) throws Fault {
  if (!"_wadl".equals(message.get(Message.QUERY_STRING))
    super.handleMessage(message)
}

And now my service "works", but any user calling for example /api/soap?_wadl can perform any SOAP operation. I could check for "org.apache.cxf.rest.message" property, but I'd rather find a better approach than risk making a security flaw.

I should also note that my goal here is only to get CXF + spring-security to work at all. SecureAnnotationsInterceptor was my backup plan. I initially tried <sec:global-method-security jsr250-annotations="enabled"/> in the beans XML, but this causes an InternalServerErrorException thrown from at org.apache.cxf.jaxrs.utils.InjectionUtils.reportServerError(InjectionUtils.java:457) in cxf-rt-frontend-jaxrs-2.7.7 jar, the real cause is line 302 (injectThroughMethod), where it catches an exception because Spring Security creates a proxy, and CXF has a reference to the Method from the real class, and calling realMethod.invoke(proxy, ...) fails because the proxy's class does not extend realMethod's class. This might be due to a @Context method setUriInfo on the implementation class rather than the interface. This method would probably be better if possible, because I'd like to use an exception mapper, which doesn't appear possible via the interceptor method.

Jason

----------------------------------------------------------------------
This email message and any attachments are for the sole use of the intended recipient(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message and any attachments.

Re: Access to WADL disabled when enabling SecureAnnotationsInterceptor

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
On 28/10/13 21:02, Winnebeck, Jason wrote:
> I have enabled the SecureAnnotationsInterceptor to observe JSR-250 annotations on my service bean, and everything is working properly, except that it is no longer possible to view the WADL. I can view services page, WSDL, and all REST service URLs as expected but not ?_wadl page. Instead, the interceptor rejects the request with a "AccessDeniedException: Method is not available : Unauthorized" exception.
>
> I'm using Spring security and its DelegatingFilterProxy to actually perform the authentication via HTTP basic.
>
> When using this interceptor, how do I control access to the service listing, WSDL, and WADL?
>

SecureAnnotationsInterceptor is at the PRE_INVOKE stage, so I wonder how 
the call reaches it when WADL is requested, given that 
JAXRSInInterceptor which runs a WADL filter is at the earlier UNMARSHAL 
stage.

SecureAnnotationsInterceptor definitely recognizes that a security 
context is set (by Spring security in your case) but I'm a bit confused 
why this issue is occurring for you

Can you give a bit more info please

Sergey
> Jason Winnebeck
>
> ----------------------------------------------------------------------
> This email message and any attachments are for the sole use of the intended recipient(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message and any attachments.
>