How about implementing the AuthorizationPolicy instead of RoutePolicy?
-- Willem Jiang Red Hat, Inc. Web: http://www.redhat.com Blog: http://willemjiang.blogspot.com (English) http://jnn.iteye.com (Chinese) Twitter: willemjiang Weibo: 姜宁willem On March 21, 2015 at 10:33:15 PM, Ed Welch (e...@edjusted.com) wrote: > I hadn't really seen this covered anywhere, so I was curious how people are > handling this? > > I'm using camel's REST dsl within the java dsl, running in Karaf. > > Java EE and Spring both have concepts of annotation based authorization to > specific > endpoints, and it seemed like it would be nice to incorporate this into the > REST dsl. > > Having found nothing off the shelf, I attempted to solve this myself by > implementing > my own RoutePolicy. In the onExchangeBegin method I look for the > Authorization header > on the camel Mesage, if it exists, I jump through some hoops with > LoginContext to validate > the user/password and also the Role. > > If something is wrong, I set an exception on the exchange > > In practice it works like this: > > in the configure() block I setup a couple route policies, one for admins, one > for viewers > (these map to JAAS roles, karaf is the realm) > > RoleAuthPolicy admin = new RoleAuthPolicy("karaf", "admin"); > RoleAuthPolicy viewer = new RoleAuthPolicy("karaf", "viewer"); > > > And then in use, you append the routePolicy in the builder: > > rest("servers") > .get().produces("application/json").route().routeId("get-servers").routePolicy(viewer).to("bean:serverManager?method=getServers()").endRest() > > .get("/{id}").produces("application/json").route().routeId("get-server").routePolicy(viewer).to("bean:serverManager?method=getServer(${headers.id})").endRest() > > .post().route().routeId("post-server").routePolicy(admin).to("bean:serverManager?method=postServer(${body})").endRest(); > > > > Pros of this method: > > you can have very granular authorization > it fits nicely with the builder patterns > > Cons: > > I created custom exceptions to handle authentication, and authorization > errors and > those have to be defined on the route so the user is prompted with what to do: > > onException(UnauthenticatedException.class) > .handled(true) > .log(LoggingLevel.WARN, log, "${exception.message}") > .process(exchange -> { > exchange.getIn().setHeader("WWW-Authenticate", "Basic"); > exchange.getIn().setBody("Unauthenticated"); > exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "text/plain"); > exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, > HttpServletResponse.SC_UNAUTHORIZED); > }); > > onException(UnauthorizedException.class) > .handled(true) > .log(LoggingLevel.WARN, log, "${exception.message}") > .process(exchange -> { > exchange.getIn().setBody("Unauthorized"); > exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "text/plain"); > exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, > HttpServletResponse.SC_FORBIDDEN); > }); > > If someone forgets to do this, you get no authentication or authorization > > I also didn't love working inside the onExchangeBegin method, because > exceptions thrown > in there are swallowed with a warning message. So any kind of implementation > mistake > or unexpected situation that throws an exception in the onExchangeBegin > method leads > too open access!!! to defend against this I wrap the entire thing in a try > catch Exception > and then set this exception on the exchange. > > > So i'm curious, how are other people solving this problem? > > Thanks, > Ed