Add CORS headers to response of j_security_check

喜夏-厌秋 提交于 2019-12-04 13:29:10

Configuring undertow subsystem in standalone.xml/domain.xml file solved this problem for me. Filters configured there handle all the requests including j_security_check one.

<subsystem xmlns="urn:jboss:domain:undertow:3.0">
            <buffer-cache name="default"/>
            <server name="default-server">
                <http-listener name="default" redirect-socket="https" socket-binding="http"/>
                <host name="default-host" alias="localhost">
                    <location name="/" handler="welcome-content"/>
                    <filter-ref name="server-header"/>
                    <filter-ref name="x-powered-by-header"/>
                    <!--CORS headers -->
                    <filter-ref name="Access-Control-Allow-Origin"/>
                    <filter-ref name="Access-Control-Allow-Methods"/>
                    <filter-ref name="Access-Control-Allow-Headers"/>
                    <filter-ref name="Access-Control-Allow-Credentials"/>
                    <filter-ref name="Access-Control-Max-Age"/>
                </host>
            </server>
            <servlet-container name="default">
                <jsp-config/>
                <websockets/>
            </servlet-container>
            <handlers>
                <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
            </handlers>
            <filters>
                <response-header name="server-header" header-value="WildFly/10" header-name="Server"/>
                <response-header name="x-powered-by-header" header-value="Undertow/1" header-name="X-Powered-By"/>
                <!-- CORS headers -->
                <response-header name="Access-Control-Allow-Origin" header-name="Access-Control-Allow-Origin" header-value="*"/>
                <response-header name="Access-Control-Allow-Methods" header-name="Access-Control-Allow-Methods" header-value="OPTIONS, GET, POST, PUT, DELETE"/>
                <response-header name="Access-Control-Allow-Headers" header-name="Access-Control-Allow-Headers" header-value="accept, authorization, content-type, x-requested-with"/>
                <response-header name="Access-Control-Allow-Credentials" header-name="Access-Control-Allow-Credentials" header-value="true"/>
                <response-header name="Access-Control-Max-Age" header-name="Access-Control-Max-Age" header-value="60"/>
            </filters>
        </subsystem>

Of course you'd better replace "*" wildcard by your GUI server's url in the Access-Control-Allow-Origin header's value attribute.

Handle the login yourself.

Instead of posting to j_security_check, post to /auth/login or something like that and handle the login. Something like this:

@POST
@Path("login")
@PermitAll
public Response postLogin() {
    String user = request.getParameter("j_username");
    String password = request.getParameter("j_password");
    StringBuffer buf = request.getRequestURL();
    URI redir = null; 
    try {redir = new URI(buf.substring(0, buf.lastIndexOf("/login")) + "/session");} 
    catch (URISyntaxException e) {}
    try {
        request.login(user, password);
        return Response.seeOther(redir).build();
    } catch (ServletException e) {
        if (e.getMessage() != null && e.getMessage().equals("UT010030: User already logged in")) {
            Response.seeOther(redir).build();
        }
        return Response.status(Status.FORBIDDEN).build();
    }
}

Based on nfedorov's answer, I came to the conclusion that he is right and that an Undertow filter is the only type of filter that can operate on container responses. So if we want to add CORS headers to these responses, we need an Undertow filter. So I wrote one:

undertow-cors-filter

Download the .zip file and unzip it in your Wildfly root folder. Then add a filter configuration to standalone.xml:

<filters>
  <filter name="undertow-cors-filter" class-name="com.stijndewitt.undertow.cors.Filter" module="com.stijndewitt.undertow.cors">

  </filter>
</filters>

Add a filter-ref to the host element (still in standalone.xml):

<host name="default-host" alias="localhost">
  <filter-ref name="undertow-cors-filter" />
</host>

This will add CORS headers allowing all origins access to all responses this server emits.

Add params to the filter definition to configure the behavior. For example, if you want the filter to apply only to responses for requests to URLS starting with /api and you only want to allow example.com and example.org access, you could use a configuration similar to this:

<filters>
  <filter name="undertow-cors-filter" class-name="com.stijndewitt.undertow.cors.Filter" module="com.stijndewitt.undertow.cors">
    <param name="urlPattern" value="^http(s)?://([^/]+)(:([^/]+))?(/([^/])+)?/api(/.*)?$" />
    <param name="policyClass" value="com.stijndewitt.undertow.cors.AllowMatching" />
    <param name="policyParam" value="^http(s)?://(www\.)?example\.(com|org)$" />   
  </filter>
</filters>

There are 3 policy classes available, AllowAll, AllowMatching and Whitelist and you can write your own custom policies if needed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!