403 errors for XHR requests in JSF app

576 views
Skip to first unread message

Jan Tošovský

unread,
Jul 1, 2021, 6:55:42 AM7/1/21
to Pac4j users mailing list
I was happy to be able to build a tiny JSF web app running on tomcat. It authenticates correctly and displays the user name, however, all partial XHR (ajax) requests are blocked by 403 error.
https://github.com/jan-tosovsky-cz/jsf-auth-sample (the app should be deployed to the ROOT folder to ensure the callback URL http://localhost:8080/callback matches).

Basically, when the command button is clicked, an itemized list of randomly generated double values should be shown.
<h:form>
    <p:dataList value="#{baseBean.itemList}"/>
    <p:commandButton action="#{baseBean.updateItemList}" update="@form" value="Update List" />
</h:form>

That XHR point to the base URL http://localhost:8080/app/index.xhtml (which works fine), but sends additional form params.

Does it mean I have to modify that request and pass additional params, or should I somehow whitelist XHR requests from authentication? Or is there better solution for this?

Thanks, Jan


Jan Tošovský

unread,
Jul 1, 2021, 8:39:54 AM7/1/21
to Pac4j users mailing list
I've removed PrimeFaces dependency to eliminate possible issues in this component library.

The problem persists. However, as default JSF forms do not use XHRs on submit buttons, it is now clear the XHR is not the issue.

I've added simple link <a> pointing to /app/index.xhtml, which redirects to the same page. The same link is used in the form action, see the rendered HTML page, but in this case it is sent using POST method. And it fails (403). 

post_get.png

So now I rather think it could be somehow related to the HTTP method, but I have no clue how to adapt my config.


Dne čtvrtek 1. července 2021 v 12:55:42 UTC+2 uživatel Jan Tošovský napsal:

Jérôme LELEU

unread,
Jul 1, 2021, 9:37:23 AM7/1/21
to Jan Tošovský, Pac4j users mailing list
Hi,

If the problem happens on a POST, it's related to the CSRF protection.

Either you need to pass the CSRF token or you may want to disable it on the protected URL.

The CSRF token is in the request attribute named pac4jCsrfToken or in a cookie with the same name.
You should send it along the form.

Or

By default, if no authorizers are defined, it's csrfCheck to check CSRF tokens.
Defining authorizers="none" removes the check.

Thanks.
Best regards,
Jérôme


--
You received this message because you are subscribed to the Google Groups "Pac4j users mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pac4j-users/cbda7c16-a7e0-482f-8516-1779b2bea6b2n%40googlegroups.com.

Jan Tošovský

unread,
Jul 1, 2021, 10:52:07 AM7/1/21
to Pac4j users mailing list
It is indeed CSFR token related. I made some experiments with passing parsed request attribute as a hidden field and it worked. But only for the first request, not subsequent ones. But...

... as I do no need role specific access levels, I suppose CSFR can be disabled completely in my case. 
Can you please elaborate "Defining authorizers="none" removes the check" ?

I had this (in https://github.com/jan-tosovsky-cz/jsf-auth-sample/blob/main/src/main/java/jsf/auth/sample/AuthConfig.java)
final Config config = new Config(clients);
config.addAuthorizer("admin", new RequireAnyRoleAuthorizer("ROLE_ADMIN"));  

When I removed the second line, that check was still in applied. Even adding the next line didn't help:
config.setAuthorizer(new IsAnonymousAuthorizer());

There is DefaultAuthorizers.NONE constant, but it returns String, not Authorizer object.

I expect I am overlooking something. Any hint how to disable that check properly? 

Dne čtvrtek 1. července 2021 v 15:37:23 UTC+2 uživatel lel...@gmail.com napsal:

Jan Tošovský

unread,
Jul 1, 2021, 11:14:08 AM7/1/21
to Pac4j users mailing list
I nailed it.

When no authorizer is set on the config object, the authorizer is null.
SecurityFilter oidcFilter = new SecurityFilter(config, "GoogleOidcClient");

We need to set it to "none" to disable check, but on the SecurityFilter object:
SecurityFilter oidcFilter = new SecurityFilter(config, "GoogleOidcClient", DefaultAuthorizers.NONE);

Now it works like a charm! Thanks a lot for this versatile library !

Jan 

Dne čtvrtek 1. července 2021 v 16:52:07 UTC+2 uživatel Jan Tošovský napsal:
Reply all
Reply to author
Forward
0 new messages