You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Venkatesh Laguduva <lb...@gmail.com> on 2016/09/09 06:24:47 UTC

in CXF, Preflight method is not getting called even though I followed every step required

I am using CXF 3.1.5 for my RESTful services and want to enable CORS only
for configued origins; to do that I have implemented options() method with
the required annotations -

in my interface,

@OPTIONS
@Path("/")
@LocalPreflight
public Response options();

in my implementation,

@Override
public Response options() {
    if (!isCORSEnabled()) {
        return Response.ok("Cross Origin Resource Sharing is not
allowed!").build();
    }
    String origin = headers.getRequestHeader("Origin").get(0);
    if(getAllowedrOrigins().contains(origin)) {
        return Response.ok()

.header(CorsHeaderConstants.HEADER_AC_ALLOW_METHODS, "GET POST DELETE
PUT")

.header(CorsHeaderConstants.HEADER_AC_ALLOW_CREDENTIALS, "false")

.header(CorsHeaderConstants.HEADER_AC_ALLOW_ORIGIN, origin)
                       .build();
    } else {
        return Response.ok("Cross Origin Resource Sharing is not
allowed!").build();
    }
}

my REST service is defined this way: in my interface (same one where I have
options() defined)-

@GET
@Path("/login")
@Produces(MediaType.TEXT_PLAIN)
public Response login();

in my implementation (same class where I have options() implemented)

@Override
public Response login() {
    return Response.ok().build();
}

my REST endpoint is running at "/auth" and I have got CORS filter set in my
blueprint.

<bean id="corsFilter"
class="org.apache.cxf.rs.security.cors.CrossOriginResourceSharingFilter"/>

<jaxrs:server address="/auth" id="auth">
    <jaxrs:invoker>
        <bean class="com.tst.web.interceptor.WebSecurityInvoker">
        </bean>
    </jaxrs:invoker>
    <jaxrs:serviceBeans>
        <ref component-id="loginServiceImpl"/>
    </jaxrs:serviceBeans>
    <jaxrs:outInterceptors>
        <bean class="com.tst.web.interceptor.WebSecurityOutInterceptor">
        </bean>
    </jaxrs:outInterceptors>
     <jaxrs:providers>
        <ref component-id="corsFilter" />
    </jaxrs:providers>
</jaxrs:server>

I hoped, I have got things in a right way but for some reasons, my
options() method is not getting called; I did some debugging through the
CORs filter, found that this filter tries to find the preflight method with
the path '/login' instead of '/'; I think, somewhere I messed up the
configuration. I have spent two days without any success; any help will be
appreciated.

Here is my client code:

$jquery.ajax({
        method: 'GET',
        url: site.endpoint + 'auth/login',
        beforeSend: function (xhr){
            xhr.setRequestHeader('Authorization',authz);
            xhr.setRequestHeader('Access-Control-Allow-Origin',
'http://localhost:8000');
            xhr.setRequestHeader('Access-Control-Expose-Headers', 'token');
        },
        success: function(data, status, xhr) {
            pauth.token = xhr.getResponseHeader("token");
            success();
        },
        error: function(xhr, status, errorThrown) {
            if(xhr.status == '403') {
                fail("Invalid Username or password. Please try again.");
            } else if (xhr.status == '500') {
                fail("Internal Server Error: Please try again after sometime.");
            } else{
                console.log("Status: " + xhr.status);
                console.log("Error Thrown :" + errorThrown);
                fail("Unknown error: Please contact System Administrator");
            }

            console.log(JSON.parse(XMLHttpRequest.responseText));
        },
        timeout: 30000
    });

    return token;
}

Re: in CXF, Preflight method is not getting called even though I followed every step required

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

I've checked the code, at the moment @LocalPreflight is not found if it 
is available on the interface - so for now put it on the implementation 
class - I'll have a look later on to fix this issue.
FYI, you can also let the filter do it, though it can not be configured 
to block CORS conditionally yet

Sergey

On 09/09/16 07:24, Venkatesh Laguduva wrote:
> I am using CXF 3.1.5 for my RESTful services and want to enable CORS only
> for configued origins; to do that I have implemented options() method with
> the required annotations -
>
> in my interface,
>
> @OPTIONS
> @Path("/")
> @LocalPreflight
> public Response options();
>
> in my implementation,
>
> @Override
> public Response options() {
>     if (!isCORSEnabled()) {
>         return Response.ok("Cross Origin Resource Sharing is not
> allowed!").build();
>     }
>     String origin = headers.getRequestHeader("Origin").get(0);
>     if(getAllowedrOrigins().contains(origin)) {
>         return Response.ok()
>
> .header(CorsHeaderConstants.HEADER_AC_ALLOW_METHODS, "GET POST DELETE
> PUT")
>
> .header(CorsHeaderConstants.HEADER_AC_ALLOW_CREDENTIALS, "false")
>
> .header(CorsHeaderConstants.HEADER_AC_ALLOW_ORIGIN, origin)
>                        .build();
>     } else {
>         return Response.ok("Cross Origin Resource Sharing is not
> allowed!").build();
>     }
> }
>
> my REST service is defined this way: in my interface (same one where I have
> options() defined)-
>
> @GET
> @Path("/login")
> @Produces(MediaType.TEXT_PLAIN)
> public Response login();
>
> in my implementation (same class where I have options() implemented)
>
> @Override
> public Response login() {
>     return Response.ok().build();
> }
>
> my REST endpoint is running at "/auth" and I have got CORS filter set in my
> blueprint.
>
> <bean id="corsFilter"
> class="org.apache.cxf.rs.security.cors.CrossOriginResourceSharingFilter"/>
>
> <jaxrs:server address="/auth" id="auth">
>     <jaxrs:invoker>
>         <bean class="com.tst.web.interceptor.WebSecurityInvoker">
>         </bean>
>     </jaxrs:invoker>
>     <jaxrs:serviceBeans>
>         <ref component-id="loginServiceImpl"/>
>     </jaxrs:serviceBeans>
>     <jaxrs:outInterceptors>
>         <bean class="com.tst.web.interceptor.WebSecurityOutInterceptor">
>         </bean>
>     </jaxrs:outInterceptors>
>      <jaxrs:providers>
>         <ref component-id="corsFilter" />
>     </jaxrs:providers>
> </jaxrs:server>
>
> I hoped, I have got things in a right way but for some reasons, my
> options() method is not getting called; I did some debugging through the
> CORs filter, found that this filter tries to find the preflight method with
> the path '/login' instead of '/'; I think, somewhere I messed up the
> configuration. I have spent two days without any success; any help will be
> appreciated.
>
> Here is my client code:
>
> $jquery.ajax({
>         method: 'GET',
>         url: site.endpoint + 'auth/login',
>         beforeSend: function (xhr){
>             xhr.setRequestHeader('Authorization',authz);
>             xhr.setRequestHeader('Access-Control-Allow-Origin',
> 'http://localhost:8000');
>             xhr.setRequestHeader('Access-Control-Expose-Headers', 'token');
>         },
>         success: function(data, status, xhr) {
>             pauth.token = xhr.getResponseHeader("token");
>             success();
>         },
>         error: function(xhr, status, errorThrown) {
>             if(xhr.status == '403') {
>                 fail("Invalid Username or password. Please try again.");
>             } else if (xhr.status == '500') {
>                 fail("Internal Server Error: Please try again after sometime.");
>             } else{
>                 console.log("Status: " + xhr.status);
>                 console.log("Error Thrown :" + errorThrown);
>                 fail("Unknown error: Please contact System Administrator");
>             }
>
>             console.log(JSON.parse(XMLHttpRequest.responseText));
>         },
>         timeout: 30000
>     });
>
>     return token;
> }
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/