【问题标题】:Access Control in Java EEJava EE 中的访问控制
【发布时间】:2014-06-20 14:56:57
【问题描述】:

我正在开发一个简单的 Java EE 应用程序,使用纯 jsp servets 以及 POJO 类和 DAO 支持。在这里实现访问控制的最佳策略是什么。

我最初想使用filter,但我不太确定它的用法,那么有什么简单的编程方式可以实现吗?我的意思是通过使用properties 文件或其他方法?

我还想保持我的应用程序重量轻。所以请提出相同的解决方案?提前致谢!

【问题讨论】:

    标签: jsp servlets acl dao pojo


    【解决方案1】:

    基本上,ACL 是在 Java EE 中通过在会话 bean 类或其方法上使用 @DeclareRoles 和 @RolesAllowed 注释来实现的,以实现编程安全性。您还可以在部署描述符 (web.xml) 中使用元素来描述您的角色和授权以实现 decalrative 安全性。

    这是来自Java EE tutorial 的程序安全示例

    package converter.ejb;
    
        import java.math.BigDecimal;
        import javax.ejb.Stateless;
        import java.security.Principal;
        import javax.annotation.Resource;
        import javax.ejb.SessionContext;
        import javax.annotation.security.DeclareRoles;
        import javax.annotation.security.RolesAllowed;
    
            @Stateless()
            @DeclareRoles("TutorialUser")
            public class ConverterBean{ 
    
                   @Resource SessionContext ctx;
                    private BigDecimal yenRate = new BigDecimal("89.5094");
                    private BigDecimal euroRate = new BigDecimal("0.0081");
    
                    @RolesAllowed("TutorialUser")
                     public BigDecimal dollarToYen(BigDecimal dollars) {
                        BigDecimal result = new BigDecimal("0.0");
                        Principal callerPrincipal = ctx.getCallerPrincipal();
                        if (ctx.isCallerInRole("TutorialUser")) {
                            result = dollars.multiply(yenRate);
                            return result.setScale(2, BigDecimal.ROUND_UP);
                        } else {
                            return result.setScale(2, BigDecimal.ROUND_UP);
                        }
                    }
    
                    @RolesAllowed("TutorialUser")
                    public BigDecimal yenToEuro(BigDecimal yen) {
                        BigDecimal result = new BigDecimal("0.0");
                        Principal callerPrincipal = ctx.getCallerPrincipal();
                        if (ctx.isCallerInRole("TutorialUser")) {
                             result = yen.multiply(euroRate);
                             return result.setScale(2, BigDecimal.ROUND_UP);
                        } else {
                             return result.setScale(2, BigDecimal.ROUND_UP);
                        }
                    }
                }
    

    您也可以在您的 servlet 中使用 HttpServletRequest 的登录、注销和身份验证方法进行身份验证,然后使用 getUserPrincipal 和 isUserInRole 进行 ACL。然后,您需要添加到 web.xml 中的 servlet 描述,以引用在 web.xml 中的元素中声明的角色。这是来自Java EE turorial 的 ACL 部分示例。

    package enterprise.programmatic_login;
    
    import java.io.*;
    import java.net.*;
    import javax.annotation.security.DeclareRoles;
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    @DeclareRoles("javaee6user")
    public class LoginServlet extends HttpServlet {
    
        /** 
         * Processes requests for both HTTP GET and POST methods.
         * @param request servlet request
         * @param response servlet response
         */
        protected void processRequest(HttpServletRequest request, 
                     HttpServletResponse response)
                throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            try {
                String userName = request.getParameter("txtUserName");
                String password = request.getParameter("txtPassword");
    
                out.println("Before Login" + "<br><br>");
                out.println("IsUserInRole?.." 
                            + request.isUserInRole("javaee6user")+"<br>");
                out.println("getRemoteUser?.." + request.getRemoteUser()+"<br>");
                out.println("getUserPrincipal?.." 
                            + request.getUserPrincipal()+"<br>");
                out.println("getAuthType?.." + request.getAuthType()+"<br><br>");
    
                try {
                    request.login(userName, password); 
                } catch(ServletException ex) {
                    out.println("Login Failed with a ServletException.." 
                        + ex.getMessage());
                    return;
                }
                out.println("After Login..."+"<br><br>");
                out.println("IsUserInRole?.." 
                            + request.isUserInRole("javaee6user")+"<br>");
                out.println("getRemoteUser?.." + request.getRemoteUser()+"<br>");
                out.println("getUserPrincipal?.." 
                            + request.getUserPrincipal()+"<br>");
                out.println("getAuthType?.." + request.getAuthType()+"<br><br>");
    
                request.logout();
                out.println("After Logout..."+"<br><br>");
                out.println("IsUserInRole?.." 
                            + request.isUserInRole("javaee6user")+"<br>");
                out.println("getRemoteUser?.." + request.getRemoteUser()+"<br>");
                out.println("getUserPrincipal?.."
                            + request.getUserPrincipal()+"<br>");
                out.println("getAuthType?.." + request.getAuthType()+"<br>");
            } finally {
                out.close();
            }
        }
    
    }
    

    查看提供的 Java EE 教程链接以获得更完整的示例和说明。

    【讨论】:

      【解决方案2】:

      如果您不打算使用某些 API(如 spring securityapache shiro),您将需要网络过滤器。

      在您的过滤器实现中,如果您想授予访问权限,只需调用

      chain.doFilter(request, response); 
      

      它将正常处理请求,否则将用户重定向到另一个页面使用

      response.sendRedirect(Url); 
      

      是个不错的选择

      【讨论】:

        猜你喜欢
        • 2011-03-18
        • 1970-01-01
        • 1970-01-01
        • 2012-05-01
        • 1970-01-01
        • 2021-10-23
        • 1970-01-01
        • 1970-01-01
        • 2012-07-14
        相关资源
        最近更新 更多