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

Reply via email to