15

I am currently following the Spring Documentation and some tutorials on Web Security. But now I have a problem, that I can't call the method antMatchers. This is the error I'm getting when building the project:

java: cannot find symbol
  symbol:   method antMatchers(java.lang.String)
  location: variable requests of type org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer<org.springframework.security.config.annotation.web.builders.HttpSecurity>.AuthorizationManagerRequestMatcherRegistry

In terms of my understanding, I should be able to use this method, so I can permit or not permit HTTP Requests to a certain URL. So my question is, why can't I use the antMatchers() method?

SecurityConfiguration class:

package de.gabriel.vertretungsplan.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests((requests) -> requests
                        .antMatchers("/vertretungsplan").hasAnyRole("SCHUELER", "LEHRER", "VERWALTUNG")
                        .anyRequest().authenticated()
                )
                .formLogin((form) -> form
                        .loginPage("/login")
                        .permitAll()
                )
                .logout((logout) -> logout.permitAll());

        return http.build();
    }

}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>de.gabriel</groupId>
    <artifactId>vertretungsplan</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>vertretungsplan</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
Gabriel
  • 233
  • 1
  • 3
  • 11

2 Answers2

30

In antMatchers() (as well as mvcMathcers() and regexMatchers()) have been deprecated and removed with Spring Security 6.0. Thus, you can't use them in a Spring Boot 3 project.

Have a look at this link if you wonder what was the rationale behind this change: Deprecate trailing slash match.

Overloaded method requestMatchers() was provided as a uniform mean for securing requests. It facilitates all the functionality of the configuration methods that have been removed from the API.

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(requests -> requests
            .requestMatchers("/vertretungsplan").hasAnyRole("SCHUELER", "LEHRER", "VERWALTUNG")
            .anyRequest().authenticated()
        )
        .formLogin(form -> form
            .loginPage("/login")
            .permitAll()
        )
        .logout(logout -> logout
            .permitAll());
    
    return http.build();
}
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
  • Thank you very much, it seems like I missed a lot in my 6 months pause They also changed from javax.persistenc to jakarte.persistence and now the thing with the antMatchers. Seems like I am going to have to get used to all the new things now, but really thanks for your answer and the link you provided ^^ – Gabriel Dec 10 '22 at 15:02
  • @Gabriel Many interesting things has come with the latest Spring release, I guess the most important change in regard to Spring Security (if you're using OAuth 2.0 or OpenID in your projects) is a new production-ready Authorization Server. – Alexander Ivanchenko Dec 10 '22 at 15:16
  • yeah that sounds interesting, but currently I am only using JPA Authentication or want to, but because this update is new or at least it seems like that there a not so many tutorials out there so I have to watch the whole new Amigoscode course on spring security xD – Gabriel Dec 10 '22 at 15:37
  • Why do you think this worked: `.requestMatchers("/user/**").hasAuthority("USER")`, but this didn't: `.requestMatchers("/user/**").hasRole("USER")`? _Even though_ I explicitly removed the default prefix and never set it or used anywhere: `@Bean public GrantedAuthorityDefaults grantedAuthorityDefaults() { return new GrantedAuthorityDefaults(""); }`. When I configured Spring Security with `WebSecurityConfigurerAdapter`, `hasRole()` worked just fine (as long as I removed the prefix) – Sergey Zolotarev Apr 02 '23 at 19:12
  • @SergeyZolotarev There's not enough code to reproduce the problem, but I'll try to clarify things. Firstly, in Spring Security we have a notion of `GrantedAuthority` which might be represented either as a Role or an Authorities (it's advisable to stick with either of the two, although technically you can use both, but it can cause a mess). In essence, both Roles and Authorities are plain strings (`GrantedAuthority` interface defines a single method `getAuthority()` returning a string). Roles describe who you are (USER, ADMIN, VISITOR, etc.), Authorities what you can do (READ, WRITE, etc.). – Alexander Ivanchenko Apr 03 '23 at 00:40
  • @SergeyZolotarev By convention, Roles are prefixed with `"ROLE_"` and methods like [`hasRole()`](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurer.AuthorizedUrl.html#hasRole(java.lang.String)) would add this prefix automatically to the argument, so that `"ADMIN"` becomes `"ROLE_ADMIN"`, Authorities are not prefixed. By defining `GrantedAuthorityDefaults` Bean, you can alter this prefix (what you have done by changing it to empty string). – Alexander Ivanchenko Apr 03 '23 at 00:41
  • @SergeyZolotarev If you look closer at [`hasRole()`](https://github.com/spring-projects/spring-security/blob/main/config/src/main/java/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurer.java#L261) and `hasAuthority()` methods, you'll find that they are using `AuthorityAuthorizationManager`. – Alexander Ivanchenko Apr 03 '23 at 00:42
  • @SergeyZolotarev And [`AuthorityAuthorizationManager.hasRole()`](https://github.com/spring-projects/spring-security/blob/main/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationManager.java#L65) under the hood invokes `hasAuthority(ROLE_PREFIX + role)`, since you've set the prefix to an empty string `hasAuthorie()` and `hasRole()` should behave in the same way when provided with the same string as an argument. Note that if there are multiple matching security rules, the one which is specified first wins. – Alexander Ivanchenko Apr 03 '23 at 00:43
  • @SergeyZolotarev Regarding `WebSecurityConfigurerAdapter` it was deprecated a while ago and eventually removed in Spring Security 6, hence you're not advised to use it. In case if the explanation doesn't clarify the problem, please post a separate Question with your security configuration and contents of the pom file. – Alexander Ivanchenko Apr 03 '23 at 00:51
-1

.requestMatchers("/assets/**").permitAll()

works for me But make sure you check your link is the same with where you insert

for example

If you use:
  <link href="assets/css/style.css" rel="stylesheet">
  
Here you need to use:
  .requestMatchers("/assets/**").permitAll()
  
If you use:
  <link href="resources/**" rel="stylesheet">
  
Here you need to use:
  .requestMatchers("/resources/**").permitAll()