Java Liferay钩子-获取用户IP登录

Java Liferay钩子-获取用户IP登录,java,liferay,Java,Liferay,我有一个Liferay钩子来读取AuthenticateByEmailAddress。。。方法 我想获取正在登录的用户的IP地址,并根据该地址限制访问 如何用这种方法获取用户IP? 我使用ServiceBuilder创建portlet。 我由Tomcat工作。只是一个想法,但是如果您想限制基于IP的应用程序,而不是在您的应用程序中这样做,您可以在部署应用程序的web服务器中这样做 例如,在Tomcat中,您可以在web.xml中设置安全约束 这也可以在JBoss中完成,这实际上取决于您使用的we

我有一个Liferay钩子来读取AuthenticateByEmailAddress。。。方法

我想获取正在登录的用户的IP地址,并根据该地址限制访问

如何用这种方法获取用户IP? 我使用ServiceBuilder创建portlet。
我由Tomcat工作。

只是一个想法,但是如果您想限制基于IP的应用程序,而不是在您的应用程序中这样做,您可以在部署应用程序的web服务器中这样做

例如,在Tomcat中,您可以在web.xml中设置安全约束

这也可以在JBoss中完成,这实际上取决于您使用的web服务器,但这似乎是最简单的解决方案,而不是在应用程序中进行过滤

编辑:在下面的注释之后,只需执行PortalTil.getHttpServletRequestrequest.getRemoteAddr;在您覆盖的方法中,将您的业务逻辑放在那里,以查看用户是否更改了ip并将此ip与持久化的ip进行比较,等等。
Liferay已经有了一些这方面的功能

这只是一个想法,但是如果您想基于IP进行限制,而不是在应用程序中进行限制,那么您可以在部署应用程序的web服务器中进行限制

例如,在Tomcat中,您可以在web.xml中设置安全约束

这也可以在JBoss中完成,这实际上取决于您使用的web服务器,但这似乎是最简单的解决方案,而不是在应用程序中进行过滤

编辑:在下面的注释之后,只需执行PortalTil.getHttpServletRequestrequest.getRemoteAddr;在您覆盖的方法中,将您的业务逻辑放在那里,以查看用户是否更改了ip并将此ip与持久化的ip进行比较,等等。
Liferay已经有了一些这样的功能

我想这些类是由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_u的表,Liferay在该表中保存有关其用户的所有信息。使用UserLocalServiceUtil,您可以获取此信息并根据需要使用它


我希望这是有帮助的。祝您的门户好运:

我想这些类是由服务生成器创建的。 然后,您可以简单地使用:

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_u的表,Liferay在该表中保存有关其用户的所有信息。使用UserLocalServiceUtil,您可以获取此信息并根据需要使用它


我希望这是有帮助的。祝您的门户网站好运:

以下是在Liferay 6.0.6中对我有用的内容

在我的钩子中,我还更改了default login.jsp。这实际上是默认的login.jsp,还有两件事。首先,从请求获取IP:

<%String ip = PortalUtil.getHttpServletRequest(renderRequest).getRemoteAddr();%>

以下是在Liferay 6.0.6中对我起作用的内容

在我的钩子中,我还更改了default login.jsp。这实际上是默认的login.jsp,还有两件事。首先,从请求获取IP:

<%String ip = PortalUtil.getHttpServletRequest(renderRequest).getRemoteAddr();%>

在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");

在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");

因为只有一个答案有效,我对这个解决方案不太满意,所以我做了更多的挖掘

以下是我的想法:

创建一个新过滤器并在liferay中注册。在那里,您将请求存储在本地线程中,并在请求结束时将其删除

之后,您可以从过滤器中获取请求

RequestFilter.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() {
    }
}

因为只有一个答案有效,我对这个解决方案不太满意,所以我做了更多的挖掘

以下是我的想法:

创建一个新过滤器并在liferay中注册。在那里,您将请求存储在本地线程中,并在请求结束时将其删除

之后,您可以从过滤器中获取请求

RequestFilter.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() {
    }
}

我想为用户创建一个自定义字段IP,并为每个用户设置它。当用户尝试登录时,我将检查远程IP。如果它等于用户自定义IP,则他/她登录会引发错误。啊,我明白了,所以如果用户更改了IP,你可以通知他们他们是从其他位置登录的?好吧,因为你覆盖了authenticateByEmailAddress,你已经成功了一半。要获取IP地址,只需执行portalTil.getHttpServletRequestrequest.getRemoteAddr;但是我在这个方法中没有请求对象。有没有办法在没有请求对象的情况下获取远程IP?检查我刚才添加的链接,您可以只使用要覆盖的对象中已有的liferay功能。我想为用户创建一个自定义字段IP,并为每个用户设置它。当用户尝试登录时,我将检查远程IP。如果它等于用户自定义IP,则他/她登录会引发错误。啊,我明白了,所以如果用户更改了IP,你可以通知他们他们是从其他位置登录的?好吧,因为你覆盖了authenticateByEmailAddress,你已经成功了一半。要获取IP地址,只需执行portalTil.getHttpServletRequestrequest.getRemoteAddr;但是我在t中没有请求对象
他的方法。有没有办法在没有请求对象的情况下获取远程IP?检查我刚才添加的链接,您可以只使用正在覆盖的对象中已有的liferay功能。对我来说,无法在那里获取FacesContext。对我来说,无法在那里获取FacesContext。因为此类是身份验证链中的挂钩,这个答案是完全错误的。因为这个类是身份验证链中的一个钩子,所以这个答案是完全错误的。这是目前为止唯一有效的答案,但不是很令人满意,因为它不是一个非常优雅的解决方案。这是目前为止唯一有效的答案,但不是很令人满意,因为它不是一个非常优雅的解决方案。
auth.failure=com.stackoverflow.MyAuthFailure