Search code examples
jbosscorsresteasysecurity-constraint

jBoss CORS support with security constraints


I'm adding authentication to my API using the web-common security constraints, but it seems to have broken my CORS filter. I've previously had it working with just the filter and no app server level authentication.

The basic idea is to require authentication on all requests expect those under the /rest/account endpoint, as these are the ones that handle the initial login and so need to be publicly accessible.

Testing in both Chrome and Postman returns a 405 Method not allowed response when the OPTIONS call is made as part of the POST request when trying to login.

Hopefully I've provided everything relevant below but let me know if anything else is needed. Thanks in advance!

My CORS filter

<filter>
    <filter-name>CORS</filter-name>
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
    <init-param>
        <param-name>cors.supportedMethods</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.supportedHeaders</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowOrigin</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowSubdomains</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>cors.supportsCredentials</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CORS</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

My security constraints

<security-constraint>
    <display-name>WebsiteUsers</display-name>
    <web-resource-collection>
        <web-resource-name>WebsiteAPI</web-resource-name>
        <description/>
        <url-pattern>/rest/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <description>Standard User authentication</description>
        <role-name>Users</role-name>
    </auth-constraint>
</security-constraint>

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Public</web-resource-name>
        <description>Matches a few special endpoints</description>
        <url-pattern>/rest/account/*</url-pattern>
    </web-resource-collection>
    <!-- No auth-constraint means everybody has access! -->
</security-constraint>

Solution

  • Try adding <http-method-omission>OPTIONS</http-method-omission> to the protected <web-resource-collection>. This should allow OPTIONS request through to your CORS filter (which would then send back proper Access-Control-Allow-Methods response header).

    See https://docs.oracle.com/cd/E19798-01/821-1841/bncbk/index.html

    Alternatively (if you need to support servlet spec < 3.0) you could define all the methods that need authentication instead (GET, POST, DELETE, PUT, etc. - except OPTIONS) - using <http-method>