2014-10-27 28 views
2

我有Karaf 3.0.2作为我的容器,它使用pax web(我认为它再次使用jetty)。我有几个servlet,我在某个别名下注册为OSGi服务。在OSGi中配置servlet的身份验证

默认情况下,etc/jetty.xml被配置为可以使用JAASLoginService,这也是我希望使用的JAASLoginService。

的问题是,我想同时使用,基本和表单认证:

  • 一切匹配/ UI/*应使用形式的认证
  • 一切匹配/ REST/*应使用基本身份验证

我尝试了很多,但我什至没有找到一个点,我可以开始。我认为可以配置每个servlet,但我想要全局执行。

任何想法?

回答

2

你有区别在这里一点。 如果使用WebApplicationBundle(WAB)部署Servlet,则拥有Web应用程序的所有常规元素。包括基本或基于表单的认证。

由于您使用的是OSGi注册Servlet的方式,因此您只能通过HttpContext进行此操作。以下示例取自Pax Web Samples,它使用基本身份验证。

public class AuthHttpContext implements HttpContext { 

    public boolean handleSecurity(HttpServletRequest req, 
     HttpServletResponse res) throws IOException { 

     if (req.getHeader("Authorization") == null) { 
      res.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
      return false; 
     } 
     if (authenticated(req)) { 
      return true; 
     } else { 
      res.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
      return false; 
     } 

    } 

    protected boolean authenticated(HttpServletRequest request) { 
     request.setAttribute(AUTHENTICATION_TYPE, HttpServletRequest.BASIC_AUTH); 

     String authzHeader = request.getHeader("Authorization"); 
     String usernameAndPassword = new String(Base64.decodeBase64(authzHeader.substring(6).getBytes())); 

     int userNameIndex = usernameAndPassword.indexOf(":"); 
     String username = usernameAndPassword.substring(0, userNameIndex); 
     String password = usernameAndPassword.substring(userNameIndex + 1); 

     // Here I will do lame hard coded credential check. HIGHLY NOT RECOMMENDED! 
     boolean success = ((username.equals("admin") && password 
      .equals("admin"))); 
     if (success) 
      request.setAttribute(REMOTE_USER, "admin"); 
     return success; 
     } 

... 
} 

对于基于表单的您需要额外的HttpContext。对于每个需要确保注册正确的HttpContext的匹配路径,还可以在Pax Web Samples处找到以下代码。

public final class Activator implements BundleActivator { 

... 

    public void start(BundleContext bc) throws Exception { 
     httpServiceRef = bc.getServiceReference(HttpService.class); 
     if (httpServiceRef != null) { 
      httpService = (HttpService) bc.getService(httpServiceRef); 

      ... 

      httpService.registerServlet("/status-with-auth", 
       new StatusServlet(), null, new AuthHttpContext()); 
     } 
    } 
... 
} 
+0

我试过了,但在/ status-with-auth它只显示由自定义上下文修改的属性的值。没有登录对话框。 – palador 2014-10-28 15:35:11

+0

相应的集成测试不会对此进行测试,它仍然有效。 https://github.com/ops4j/org.ops4j.pax.web/blob/master/pax-web-itest/pax-web-itest-container/pax-web-itest-container-jetty/src/test/ java/org/ops4j/pax/web/itest/jetty/AuthenticationIntegrationTest.java – 2014-10-28 19:56:23

+0

但它只是在/ status-with-auth中测试实际内容,甚至不执行登录 - 这正是我想要的。我希望每个访问servlet的人都必须通过基本或表单身份验证来验证自己的身份。 – palador 2014-10-29 09:07:04

相关问题