如何在spring security中只通过ip地址验证用户?

时间:2016-07-11 09:59:20

标签: java spring spring-security

我有用户表。此表中有“ip_address”列。

我有服务器 - java服务器 我在春季启动时有网络应用程序。

Spring boot通过rest来与java服务器通信。

我需要通过ip实现系统中的authonticate用户。 用户打开网页 - spring boot app获取remoteIpAddress(String ipAddress = request.getRemoteAddr();)并将其传递给url中的java服务器。 java server在表用户的db中ckeck这个ip,如果用户可以登录,则将该用户返回到spring boot app。

我想通过弹簧安全来实现这一点。但是当我打开网页时,在浏览器中打开对话框窗口输入登录名和密码。但我不需要登录和密码。如果用户不为null,我需要 - 允许访问页面并保存用户。

如果我输入登录名和密码并按“确定”按钮,我将移至我的IPAddressBasedAuthenticationProvider

@Component
public class IPAddressBasedAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    AuthService authService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String ipAddress = request.getRemoteAddr();
        AuthLkUser authLkUserByIp = authService.getAuthLkUserByIp(ipAddress);

        if (authLkUserByIp == null) return null;

        boolean b = authService.checkAuthLkUser(authLkUserByIp);
        if (b) return null;
        final List<GrantedAuthority> grantedAuths = new ArrayList<>();
        GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_ADMIN");
        grantedAuths.add(grantedAuthority);
        UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(authentication.getName(), authentication.getCredentials(), grantedAuths);
        result.setDetails(authentication.getDetails());
        return result;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}

并在此类中将用户保存到会话中。之后,当我打开网页时,我不需要输入登录名和密码。它包含在会话中。但是我的wep页面没有错误打开

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Jul 11 14:27:59 ALMT 2016
There was an unexpected error (type=Forbidden, status=403).
Access is denied

2 个答案:

答案 0 :(得分:1)

您可以使用Spring提供的基于表达式的访问控制。要保护单个网址,您可以执行以下操作:

<http use-expressions="true">
    <intercept-url pattern="/admin*"
        access="hasRole('admin') and hasIpAddress('192.168.1.0/24')"/>
    ...
  </http>

如果您创建了表达式,如果他有角色admin并且他的IP地址是xxx.xxx.x.x,那么它是允许的。所以你正在寻找hasIpAddress。 有关基于表达式的访问控制的更多信息,请参见docs

如果要为Spring Boot创建此限制,并且如果您使用的是Apache Tomcat,那么您可以启用Servlet过滤器(here是描述),然后您只需启用远程地址过滤器,然后设置您要允许的地址。更多abouy此过滤器位于Apache Tomcat docs

另一个选择是,如果你将使用Spring Security。 There is WebAuthenticationDetails ,提供方法 getRemoteAddress()

答案 1 :(得分:1)

对于使用嵌入式Apache Tomcat容器运行的 Spring Boot应用程序,您可以使用Apache Tomcat中的org.apache.catalina.filters.RemoteAddrFilter。

 @Bean
 public FilterRegistrationBean remoteAddressFilter() {
  FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
  RemoteAddrFilter filter = new RemoteAddrFilter();
 // filter.setAllow("127.0.0.1");
  filter.setAllow("127\\.0\\.0\\.1");
  filterRegistrationBean.setFilter(filter);
  filterRegistrationBean.addUrlPatterns("/gs/serving-web-content/testParameters");
  return filterRegistrationBean;
 }
  

允许:远程的正则表达式(使用java.util.regex)   将客户端的IP地址与之进行比较。如果指定了此属性,   远程地址必须匹配此请求才能被接受。如果这   如果未指定属性,则除非接受所有请求   远程地址匹配拒绝模式。

您可以参考此文章 - How do I restrict access to my application by IP address?