我有一个 Liferay-Hookovrride
方法AuthenticateByEmailAddress(...)
。
我想获取正在登录的用户的IP地址并根据它限制访问。
如何通过这种方法获取用户 IP?
我使用 ServiceBuilder 来制作 portlet。
我在 Tomcat 工作。
这就是在 Liferay 6.0.6 中对我有用的东西。
在我的钩子中,我还更改了默认 login.jsp。这实际上是带有两个附加内容的默认 login.jsp。首先,从请求中获取 IP:
<%String ip = PortalUtil.getHttpServletRequest(renderRequest).getRemoteAddr();%>
并添加额外的参数:
<portlet:actionURL secure="<%= PropsValues.COMPANY_SECURITY_AUTH_REQUIRES_HTTPS || request.isSecure() %>" var="loginURL">
<portlet:param name="saveLastPath" value="0" />
<portlet:param name="struts_action" value="/login/login" />
<portlet:param name="requestIp" value="<%= ip %>" />
</portlet:actionURL>
现在,在您覆盖的 AuthenticateByEmailAddress() 中,您可以从 parameterMap 中获取它:
String ip = parameterMap.get("requestIp")[0];
只是一个想法,但是如果您想基于 IP 进行限制,而不是在您的应用程序中执行此操作,您可以在您正在部署应用程序的 Web 服务器中执行此操作。
例如,在 Tomcat 中,您可以在 web.xml 中放置安全约束。
通过 ip 限制访问 这也可以在 JBoss 中完成,这实际上取决于您使用的 Web 服务器,但这似乎是最简单的解决方案,而不是在您的应用程序中进行过滤。
编辑:在下面的评论之后,只需PortalUtil.getHttpServletRequest(request).getRemoteAddr();
在您覆盖的方法中执行并将您的业务逻辑放在那里以查看用户是否更改了 ip(将此 IP 与持久的 IP 等进行比较)。Liferay在这里已经有了一些这样的功能
在 Liferay Portal 中,我通过以下方式获得了正确的客户端 IP 地址。
FacesContext facesContext = FacesContext.getCurrentInstance();
PortletRequest portletRequest = (PortletRequest) facesContext.getExternalContext().getRequest();
HttpServletRequest request = PortalUtil.getHttpServletRequest(portletRequest);
HttpServletRequest originalServletRequest = PortalUtil.getOriginalServletRequest(request);
String ipAddress=originalServletRequest.getHeader("x-forwarded-for");
我想这些类是由 Service Builder 制作的。然后你可以简单地使用:
String user = request.getRemoteUser();//take current logged in user ID
int userId = Integer.valueOf(user);//convert it into integer
User newUser = UserLocalServiceUtil.getUser(userId);//get the Liferay user using the user ID you get in the line above
userIp=newUser.getLoginIP();//after you have the current user take his LoginIP with the get method that Liferay has already
在 Liferay 数据库中,您有一个名为user_
Liferay 的表,其中保存了有关其用户的所有类型的信息。使用UserLocalServiceUtil
您可以获取此信息并根据需要使用它。
我希望这会有所帮助。祝你的门户好运:)
由于只有一个答案有效,而且我对这个解决方案不太满意,所以我做了更多的挖掘。
这是我想出的:
创建一个新过滤器并将其注册到您的 liferay 中。在那里,您将请求存储在本地线程中,并在请求结束时将其删除。
之后,您可以从过滤器中获取请求。
请求过滤器.java
@WebFilter(urlPatterns = "/*")
public class RequestFilter implements Filter {
private static final ThreadLocal<HttpServletRequest> REQUEST = new ThreadLocal<>();
public static HttpServletRequest getRequest() {
HttpServletRequest req = REQUEST.get();
if (req == null) {
throw new IllegalStateException("Attempt to fetch thread-local request outside of filter chain");
}
return req;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
REQUEST.set((HttpServletRequest)req);
try {
chain.doFilter(req, res);
} finally {
REQUEST.remove();
}
}
@Override
public void destroy() {
}
}
MyAuthFailure.java
public class MyAuthFailure implements AuthFailure {
private static final Log LOG = LogFactoryUtil.getLog(MyAuthFailure.class);
@Override
public void onFailureByEmailAddress(long companyId, String emailAddress,
Map<String, String[]> headers, Map<String, String[]> params) throws AuthException {
logFailure(companyId, emailAddress);
}
@Override
public void onFailureByScreenName(long companyId, String screenName,
Map<String, String[]> headers, Map<String, String[]> params) throws AuthException {
logFailure(companyId, screenName);
}
@Override
public void onFailureByUserId(long companyId, long userId,
Map<String, String[]> headers, Map<String, String[]> params) throws AuthException {
logFailure(companyId, userId);
}
protected void logFailure(String user) {
String ip = RequestFilter.getRequest().getRemoteAddr();
LOG.error("User " + user + " tried to login from IP " + ip);
}
}
liferay-hook.xml
<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd">
<hook>
<portal-properties>portal.properties</portal-properties>
<custom-jsp-dir>/WEB-INF/jsp</custom-jsp-dir>
<servlet-filter>
<servlet-filter-name>requestFilter</servlet-filter-name>
<servlet-filter-impl>com.stackoverflow.RequestFilter</servlet-filter-impl>
</servlet-filter>
</hook>
门户网站属性
auth.failure=com.stackoverflow.MyAuthFailure