[keycloak-user] Enabling a public rest service

Sebastien Blanc sblanc at redhat.com
Fri Dec 9 03:48:38 EST 2016


Hi,
Yes mixing public resources + protected resources + CORS can be painful
indeed. We need to enhance dev experience on this point. But this should
work : you implement a ContainerResponseFilter that only applies for your
public resources, so it won't mess with KC own CORS stuff :

import javax.ws.rs.ext.Provider;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;

@Provider
public class NewCrossOriginResourceSharingFilter
        implements
            ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext request,
            ContainerResponseContext response) {
        if(request.getUriInfo().getPath().equals("/listaPublica
<http://ramona.localdomain:8080/ramona-backend/listaPublica>")){
          response.getHeaders().putSingle("Access-Control-Allow-Origin",
"*");
          response.getHeaders().putSingle("Access-Control-Expose-Headers",
                "Location");
          response.getHeaders().putSingle("Access-Control-Allow-Methods",
                "GET, POST, PUT, DELETE");
          response.getHeaders()
                .putSingle("Access-Control-Allow-Headers",
                        "Content-Type, User-Agent, X-Requested-With,
X-Requested-By, Cache-Control");

response.getHeaders().putSingle("Access-Control-Allow-Credentials",
                "true");
        }
    }
}

I just did the test myself and it should work.



On Fri, Dec 9, 2016 at 1:48 AM, Juan Diego <juandiego83 at gmail.com> wrote:

> Hi,
>
> Maybe I am looking at this the wrong way.  I have 2 web pages on separate
> domains. One page is public, so you don't need to log and the other is
> private and you need a user and a password.
> Both should connect to my Rest API.
> I am using java and wildfly 10 for my back end, and Angularjs for my
> frontend.  In my private web page I dont have any problems connecting to my
> backend.
>
> In my public page I am getting cors error and I kind of know why it happens
> but I do not know how to solve it.
>
>
> I created this in my web.xml
>
> <security-constraint>
>         <web-resource-collection>
>             <web-resource-name>ramonapublic</web-resource-name>
>             <url-pattern>/listaPublica</url-pattern>
>             <url-pattern>/listaPublica/*</url-pattern>
>         </web-resource-collection>
>     </security-constraint>
>
>     <security-constraint>
>         <web-resource-collection>
>             <web-resource-name>ramona</web-resource-name>
>             <url-pattern>/</url-pattern>
>         </web-resource-collection>
>         <auth-constraint>
>             <role-name>usuarios</role-name>
>         </auth-constraint>
>     </security-constraint>
>
>
> ramonapublic is the public rest service.  If I use curl I get this and I
> have no problem,
> curl  http://ramona.localdomain:8080/ramona-backend/listaPublica -X POST
> -H
> 'ramonaclient.localdomain',
>
> I get this
>
> [{"codigo":1006,"titulo":"Avengers2.mp4","paths3":"archivos/1006/","
> nombreArchivo":"Avengers2.mp4","tamano":13977910,"bitrate":
> null,"duracion":null,"hash":null,"mimeType":"video/mp4","
> fechaSubida":1480518881829,"tipoArchivo":
> ..............
>
> If I use firefox or chrome I get this
>
> XMLHttpRequest cannot load http://localhost:8080/ramona-
> backend/listaPublica.
> No 'Access-Control-Allow-Origin' header is present on the requested
> resource. Origin 'http://ramonaclient.localdomain' is therefore not
> allowed
> access.
>
> For what I can tell the browsers are blocking the response because there
> is no Access-Control. (This only happens with my public page, my private
> page with keycloak works perfect)
>
>
> So for what I can tell is that listaPublic is being called in the backend
> but because it is a public security constrain that is not using keycloaks
> tokens it is not getting a proper header.
>
> If I add this to my JaxRxActivator
>
> private Set<Object> singletons = new HashSet<Object>();
>     private Set<Class<?>> classes = new HashSet<Class<?>>();
>
>     public JaxRsActivator() {
>         // no instance is created, just class is listed
>         classes.add(PublicPlaylistRest.class);
>
>
>         CorsFilter corsFilter = new CorsFilter();
>         corsFilter.getAllowedOrigins().add("http://ramonaclient.
> localdomain
> ");
>         corsFilter.setAllowedHeaders("Content-Type");
>         singletons.add(corsFilter);
>     }
>
>     @Override
>     public Set<Class<?>> getClasses() {
>         return classes;
>     }
>
>     @Override
>     public Set<Object> getSingletons() {
>         return singletons;
>     }
>
> It works on the public side but it messes up the headers on the private
> side so I cannot use this.  It interferes with keycloaks own cors.
> _______________________________________________
> keycloak-user mailing list
> keycloak-user at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-user
>


More information about the keycloak-user mailing list