我正在使用JSF制作一个应用程序,如果用户未登录,我想使用@WebFilter将用户从每个页面(不包括login / register.xhtml)重定向到login.xhtml。问题是重定向后我看到的只是空白页。
我认为它正在过滤包括bootstrap.css在内的所有资源,因此我使用了以下方法:
if (req.getRequestURI().startsWith(req.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) {
chain.doFilter(request, response);
return;
}
但是它什么也没做。
这是我的LoginFilter.java
@WebFilter("*")
public class LoginFilter extends HttpFilter {
@Inject
CurrentSession currentSession;
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String currentPath = req.getContextPath() + req.getServletPath();
if (!userIsLogged()) {
if(!currentPath.equals("/app/register.xhtml") && !currentPath.equals("/app/login.xhtml"))
res.sendRedirect(req.getContextPath() + "/login.xhtml");
}
else
chain.doFilter(req, res);
}
有人可以指导我该添加些什么吗?
答案 0 :(得分:0)
我不认为您应该编写自定义过滤器,因为JavaEE具有内置的Security Mechanism用于认证和授权。
您只需要在WEB-INF/web.xml
文件中进行配置即可。
这是一个最小的项目:
sample-webapp ├── pom.xml └── src └── main ├── java ├── resources │ └── messages.properties └── webapp ├── pages │ ├── admin (restricted for ADMINISTRATORs only) │ │ └── admin.xhtml │ ├── dashboard.xhtml (available for all logged-in users) │ ├── protected.xhtml │ └── public (unrestricted pages) │ ├── login.xhtml │ └── register.xhtml ├── resources (unrestricted public resources) │ └── css │ └── style.css └── WEB-INF ├── faces-config.xml ├── jboss-web.xml └── web.xml
所有静态资源(图像,样式表等)位于webapp/resources
下。 JSF文件位于webapp/pages/...
下,但这只是一个示例。期望的行为
webapp/pages/public
下的所有内容)都是公开的webapp/pages/
下的所有其他页面均受保护,并且可供所有登录用户使用webapp/pages/admin
下的页面仅可用于ADMINISTRATORS。在web.xml中,只需配置以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<welcome-file-list>
<welcome-file>/pages/dashboard.xhtml</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>stackoverflow-auth-realm</realm-name>
<form-login-config>
<form-login-page>/pages/public/login.xhtml</form-login-page>
<form-error-page>/pages/public/login.xhtml?showerror=true</form-error-page>
</form-login-config>
</login-config>
<security-constraint>
<display-name>Allowed for admin only</display-name>
<web-resource-collection>
<web-resource-name>Admin</web-resource-name>
<url-pattern>/pages/admin/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>ADMINISTRATOR</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>Unrestricted access</display-name>
<web-resource-collection>
<web-resource-name>Unrestricted</web-resource-name>
<url-pattern>/pages/public/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<!-- auth-constraint section is missing which means theese resources are available for everyone -->
</security-constraint>
<security-constraint>
<display-name>Allowed for all logged in users</display-name>
<web-resource-collection>
<web-resource-name>LoggedIn</web-resource-name>
<url-pattern>/pages/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name> <!-- Wildcard role-name means authentication is required but theese resources are available for every roles -->
</auth-constraint>
</security-constraint>
<security-role>
<role-name>ADMINISTRATOR</role-name>
</security-role>
<security-role>
<role-name>*</role-name>
</security-role>
<servlet>
<servlet-name>FacesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
在login.xhtml中有一些要求。
j_security_check
操作j_username
和j_password
,如下所示:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:ui="http://java.sun.com/jsf/facelets">
<h:body>
<div class="login-box">
<ui:fragment rendered="#{param.showerror}">
<div class="text-danger">
<h4>#{msg['login.error']}</h4>
</div>
</ui:fragment>
<form method="post" action="j_security_check">
<p:inputText id="j_username" placeholder="#{msg['login.username']}"
required="true" autocomplete="off"
requiredMessage="#{msg['login.error.username']}"/>
<p:password id="j_password" placeholder="#{msg['login.password']}" required="true" autocomplete="off"
requiredMessage="#{msg['login.error.password']}"/>
<button><h:outputText value="#{msg['login.submit']}"/></button>
</form>
</h:body>
</html>
假设您有三种不同的最终用户类型。
login.xhtml
和register.xhtml
否则,该用户将被重定向到登录表单。 webapp/pages
下的所有页面,但webapp/pages/admin
下的页面除外。如果用户尝试访问管理页面,它将
得到禁止的响应。答案 1 :(得分:0)
问了这个问题已经有一段时间了,但是我认为有人可能会遇到这个帖子,所以我将解决方案发布在这里。
@WebFilter("*")
public class LoginFilter extends HttpFilter {
@Inject
CurrentSession currentSession;
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
//Resources
boolean isResource = req.getRequestURI().startsWith(req.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");
if(isResource)
chain.doFilter(req, res);
}
我使用上下文路径和资源标识符来检查当前正在加载的文件是否为资源。