Search code examples
javaspringspring-security

Matching IP address with authorizeHttpRequests


I've read in Spring Security Reference that AuthorizationFilter supersedes FilterSecurityInterceptor. So I'm trying to migrate my application to this newer method.

I have something like

                http.authorizeRequests()
                        .mvcMatchers("/")
                        .hasIpAddress("127.0.0.1")

According to the linked page I should be able to write something like

                http.authorizeHttpRequests()
                        .mvcMatchers("/")
                        .access("hasIpAddress('127.0.0.1')")

but there's no access(String) method. I even tried to paste verbatim code from the documentation:

@Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {
    http
        // ...
        .authorizeHttpRequests(authorize -> authorize                                  
            .mvcMatchers("/resources/**", "/signup", "/about").permitAll()         
            .mvcMatchers("/admin/**").hasRole("ADMIN")                             
            .mvcMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")   
            .anyRequest().denyAll()                                                
        );

    return http.build();
}

which does not compile for the same reason.

Here's compilation error:

Application.java:103:55
java: incompatible types: java.lang.String cannot be converted to org.springframework.security.authorization.AuthorizationManager<org.springframework.security.web.access.intercept.RequestAuthorizationContext>

How do I use authorizeHttpRequests with IP addresses or string expression? Is it issue with documentation?

I'm using Spring Boot 2.7.0 and Spring Security 5.7.1


Solution

  • This does appear to be an issue with the docs. There is not currently a built-in implementation providing the hasIpAddress(String) access check, but you can use the IpAddressMatcher class to implement an AuthorizationManager capable of performing it.

    Here's an example configuration:

    @EnableWebSecurity
    public class SecurityConfiguration {
    
        @Bean
        public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
            http
                .authorizeHttpRequests((authorizeRequests) -> authorizeRequests
                    .requestMatchers("/").access(hasIpAddress("127.0.0.1"))
                    .anyRequest().authenticated()
                )
                .formLogin(Customizer.withDefaults())
                .httpBasic(Customizer.withDefaults());
            return http.build();
        }
    
        private static AuthorizationManager<RequestAuthorizationContext> hasIpAddress(String ipAddress) {
            IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(ipAddress);
            return (authentication, context) -> {
                HttpServletRequest request = context.getRequest();
                return new AuthorizationDecision(ipAddressMatcher.matches(request));
            };
        }
    
    }