授权过滤器(JEE6)中的错误

| 我正在为我的JEE6应用程序编写一个授权过滤器,以便能够将对某些用户的访问限制在某些页面上。由于某种原因,浏览器根本不显示任何页面(我只看到白色)。在某处必须有一个错误,但是我不知道在哪里,我是JEE6安全的新手,并且我正在尝试以最简单的方式实现身份验证机制。 这是我的源代码 过滤器:
public class RestrictPageFilter implements Filter {

    private FilterConfig fc;
    private InputStream in;
    private Access access;

    public void init(FilterConfig filterConfig) throws ServletException {
        // The easiest way to initialize the filter
        fc = filterConfig;

        // Prepare the parsing
        try {
            in = Thread.currentThread().getContextClassLoader()
                    .getResourceAsStream(\"allowedpages.xml\");
            Access access = (Access) JAXBContext.newInstance(Access.class)
                    .createUnmarshaller().unmarshal(in);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpSession session = req.getSession(true);
        String pageRequested = req.getRequestURL().toString();

        // Get the value of the current logged user
        Role currentUser = (Role) session.getAttribute(\"userRole\");
        if (currentUser != null) {
            if (currentUser.getType().equals(\"BUYER\")) {
                List<String> buyerPages = access.getBuyer().getPages();
                for (String s : buyerPages) {
                    if (pageRequested.contains(s)) {
                        chain.doFilter(request, response);
                    } else {
                        resp.sendRedirect(\"main.xml\");
                    }
                }
            } else if (currentUser.getType().equals(\"SELLER\")) {
                List<String> buyerPages = access.getSeller().getPages();
                for (String s : buyerPages) {
                    if (pageRequested.contains(s)) {
                        chain.doFilter(request, response);
                    } else {
                        resp.sendRedirect(\"main.xml\");
                    }
                }
            } else if (currentUser.getType().equals(\"ADMINISTRATOR\")) {
                List<String> buyerPages = access.getAdministrator().getPages();
                for (String s : buyerPages) {
                    if (pageRequested.contains(s)) {
                        chain.doFilter(request, response);
                    } else {
                        resp.sendRedirect(\"main.xml\");
                    }
                }
            }
        }
    }

    public void destroy() {
        // Not needed
    }
}
为了支持此过滤器,我使用了一个.xml文件(位于WEB-INF / classes中),该文件包含允许的页面以及一个将.xml的详细信息作为对象存储的bean:
<access>
    <buyer>
        <page>buyoffer.xhtml</page>
        <page>faq.xhtml</page>
        <page>index.jsp</page>
        <page>login.xhtml</page>
        <page>main.xhtml</page>
        <page>registrationSucceded.xhtml</page>     
    </buyer>
    <seller>
        <page>sellerpanel.xhtml</page>
        <page>faq.xhtml</page>
        <page>index.jsp</page>
        <page>login.xhtml</page>
        <page>main.xhtml</page>
        <page>registrationSucceded.xhtml</page>     
    </seller>
    <administrator>
        <page>sellerpanel.xhtml</page>
        <page>faq.xhtml</page>
        <page>index.jsp</page>
        <page>login.xhtml</page>
        <page>main.xhtml</page>
        <page>registrationSucceded.xhtml</page>     
    </administrator>
</access>
-
package simplebeans;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Access {

    @XmlElement
    private User buyer;

    @XmlElement
    private User seller;

    @XmlElement
    private User administrator;

    public User getBuyer() {
        return buyer;
    }

    public User getSeller() {
        return seller;
    }

    public User getAdministrator() {
        return administrator;
    }

    @XmlRootElement
    public static class User {

        @XmlElement(name=\"page\")
        private List<String> pages;

        public List<String> getPages() {
            return pages;
        }

    }

}
这是我将过滤器添加到web.xml文件的方式:
<!--Page restriction filter -->
    <filter>
        <filter-name>restrict</filter-name>
        <filter-class>filters.RestrictPageFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>restrict</filter-name>
        <url-pattern>*.xhtml</url-pattern>
    </filter-mapping>
您认为我在浏览器中只能看到白色的原因是什么? 我尝试使用URL导航到某些页面,但只能看到白色。 更新资料 我进行了一些更改,以允许未登录的用户看到某些页面,但我得到了NPE: 在doFilter方法上的更改:
public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpSession session = req.getSession(true);
        String pageRequested = req.getRequestURL().toString();

        // Get the value of the current logged user
        Role currentUser = (Role) session.getAttribute(\"userRole\");
        boolean authorized = false;

        if (!pageRequested.contains(\"main.xhtml\") && currentUser != null) {

            switch (currentUser.getType()) {
            case BUYER:
                for (String s : access.getBuyer().getPages()) {
                    if (pageRequested.contains(s)) {
                        authorized = true;
                    }
                }
                break;
            case SELLER:
                for (String s : access.getSeller().getPages()) {
                    if (pageRequested.contains(s)) {
                        authorized = true;
                    }
                }
                break;
            case ADMINISTRATOR:
                for (String s : access.getAdministrator().getPages()) {
                    if (pageRequested.contains(s)) {
                        authorized = true;
                    }
                }
                break;
            }
        }
        else {
            for (String s : access.getVisitor().getPages()) {
                if (pageRequested.contains(s)) {
                    authorized = true;
                }
            }
        }


        if (authorized || pageRequested.contains(\"main.xhtml\")) {
            chain.doFilter(request, response);
        } else {
            resp.sendRedirect(\"main.xhtml\");
        }
    }
xml文件中的更改:
<visitor>
        <page>faq.xhtml</page>      
        <page>login.xhtml</page>
        <page>main.xhtml</page> 
        <page>registration.xhtml</page>
        <page>registrationbuyer.xhtml</page>    
        <page>registrationseller.xhtml</page>
    </visitor>
对Access Bean所做的更改:
@XmlElement
    private User visitor;

public User getVisitor() {
        return visitor;
    }
    
已邀请:
如果您没有看到任何内容,则表明过滤器已阻止该请求。即它既没有继续链,也没有转发或重定向请求。您的代码流是不合逻辑的。当当前用户为
null
或当前用户没有任何这些角色时,您还应该执行重定向。在整个过滤器的代码中,您还应该仅有效地调用一次
chain.doFilter()
response.sendRedirect()
。现在,您正在循环中为每个页面多次调用它们。这些方法调用不会神奇地终止
for
循环。 我建议如下重写主
if
   boolean authorized = false;

   if (currentUser != null) {
        if (currentUser.getType().equals(\"BUYER\")) {
            for (String s : access.getBuyer().getPages()) {
                if (pageRequested.contains(s)) {
                    authorized = true;
                    break;
                }
            }
        } else if (currentUser.getType().equals(\"SELLER\")) {
            for (String s : access.getSeller().getPages()) {
                if (pageRequested.contains(s)) {
                    authorized = true;
                    break;
                }
            }
        } else if (currentUser.getType().equals(\"ADMINISTRATOR\")) {
            for (String s : access.getAdministrator().getPages()) {
                if (pageRequested.contains(s)) {
                    authorized = true;
                    break;
                }
            }
        }
    }

    if (authorized) {
        chain.doFilter(request, response);
    } else {
        resp.sendRedirect(\"main.xhtml\");
    }
我个人也将
CurrentUser#getType()
enum
做为一个,所以您可以使用
switch
代替
if else if else if else ...
,并将三个重复的块重构为一个辅助方法。 更新:根据您的重定向循环问题,如果您的过滤器映射到通用网址格式(例如
/*
(也包含
main.xhtml
)),而不是例如
/secured/*
,那么当当前请求的页面是ѭ18you时,您无需重定向请求,而是需要继续链接。您可以通过在当前请求的页面为
main.xhtml
时跳过
if
的主要检查。无论如何,您都不关心ѭ18的授权。     

要回复问题请先登录注册