title: Spring Security does not recognize roles - PreAuthorize or Hibernate Problem?
body: <p>I am trying to get into Spring security with a Spring/Angular stack and found the awsome code of bezcoder which can be looked up here</p>
  <p><a href="https://github.com/bezkoder/angular-10-jwt-authentication" rel="nofollow noreferrer">https://github.com/bezkoder/angular-10-jwt-authentication</a>
  and
  <a href="https://github.com/bezkoder/spring-boot-spring-security-jwt-authentication" rel="nofollow noreferrer">https://github.com/bezkoder/spring-boot-spring-security-jwt-authentication</a></p>
  <p>Signin and signup works, however, I have trouble with the authorisation for certain access points. For instance, I cannot enter the url localhost:8080/api/test/user - if I try I get &quot;Error:Unauthorized&quot;</p>
  <p>I think I narrowed the problem down to the handling of roles by the @PreAuthorize annotation. In the following &quot;TestController&quot;, the @PreAuthorize(&quot;permitAll()&quot;), as set on the public String allAccess() function works,
  however, all other functions with @PreAuthorize which refer to a certain role do not. The controller:</p>
  <pre><code>package com.savetravel.SaveTravel.Controller;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.security.access.prepost.PreAuthorize;
  import org.springframework.web.bind.annotation.CrossOrigin;
  import org.springframework.web.bind.annotation.GetMapping;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.RestController;
  
  import com.savetravel.SaveTravel.Repositories.UserRepository;
  
  
  @CrossOrigin(origins = &quot;*&quot;, maxAge = 3600)
  @RestController
  @RequestMapping(&quot;/api/test&quot;)
  public class TestController {
  
      @Autowired
      UserRepository userRepositoy;
      
      @PreAuthorize(&quot;permitAll()&quot;)
      @GetMapping(&quot;/all&quot;)
      public String allAccess() {
          return &quot;Public Content.&quot;;
      }
      
      @GetMapping(&quot;/user&quot;)
      @PreAuthorize(&quot;hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')&quot;)
      public String userAccess() {
          return &quot;User Content.&quot;;
      }
  
      @GetMapping(&quot;/mod&quot;)
      @PreAuthorize(&quot;hasRole('MODERATOR') or hasRole('ADMIN')&quot;)
      public String moderatorAccess() {
          return &quot;Moderator Board.&quot;;
      }
      
      @GetMapping(&quot;/admin&quot;)
      @PreAuthorize(&quot;hasRole('ROLE_ADMIN')&quot;)
      public String adminAccess() {
          return &quot;Admin Board.&quot;;
      }
      
      
  }
  </code></pre>
  <p>and my WebSecurityConfig</p>
  <pre><code>package com.savetravel.SaveTravel;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  import org.springframework.security.config.http.SessionCreationPolicy;
  import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  import org.springframework.security.crypto.password.PasswordEncoder;
  import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  import com.savetravel.SaveTravel.Security.Services.UserDetailsServiceImpl;
  import com.savetravel.SaveTravel.Security.jwt.AuthEntryPointJwt;
  import com.savetravel.SaveTravel.Security.jwt.AuthTokenFilter;
  
  
  @Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(
          // securedEnabled = true,
          // jsr250Enabled = true,
          proxyTargetClass = true,
          prePostEnabled = true)
  public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
      
      @Autowired
      UserDetailsServiceImpl userDetailsService;
  
      @Autowired
      public AuthEntryPointJwt unauthorizedHandler;
  
      @Bean
      public AuthTokenFilter authenticationJwtTokenFilter() {
          return new AuthTokenFilter();
      }
  
      @Override
      public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
          authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
      }
  
      @Bean
      @Override
      public AuthenticationManager authenticationManagerBean() throws Exception {
          return super.authenticationManagerBean();
      }
  
      @Bean
      public PasswordEncoder passwordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http.cors().and().csrf().disable()
              .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
              .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
              .authorizeRequests().antMatchers(&quot;/api/auth/**&quot;).permitAll()
              .antMatchers(&quot;/api/test/**&quot;).permitAll()
              .anyRequest().authenticated();
  
          http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
      }
  }
  
  </code></pre>
  <p>If I remove the @PreAuthorize annotations for the roles from the functions in the controller everything works (falling back to the WebSecurityConfig, which is not how its meant to be)
  I am quite puzzled, as removing the @PreAuthorize annotations and altering the configure() function in the WebSecurityConfig with .authorizeRequests().antMatchers(&quot;/api/test/user&quot;).hasRole(&quot;USER&quot;)does not have an effect either say:</p>
  <pre><code>@Override
      protected void configure(HttpSecurity http) throws Exception {
          http.cors().and().csrf().disable()
              .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
              .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
              .authorizeRequests()
              .antMatchers(&quot;/api/test/user&quot;).hasRole(&quot;USER&quot;)
              .antMatchers(&quot;/api/auth/**&quot;).permitAll()
              .antMatchers(&quot;/api/test/**&quot;).permitAll()
              .anyRequest().authenticated();
  
          http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
      }
  </code></pre>
  <p>It seems that the backend doesn't consider roles at all. The only thing I changed is that I use Hibernate H2 instead of MySQL, as it is used in the original code. Consequently, my application.properties looks like that (the original configuration is commented out):</p>
  <pre><code>spring.datasource.url=jdbc:h2:mem:savetravel;DATABASE_TO_UPPER=false
  spring.h2.console.enabled=true
  logging.level.org.hibernate.SQL=DEBUG
  logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
  spring.jpa.hibernate.hbm2ddl.auto=create
  spring.datasource.username=myusername
  spring.datasource.password=mypassword
  spring.datasource.driver-class-name=org.h2.Driver
  spring.datasource.platform=h2
  spring.datasource.initialize=true
  
  #Connection connection = DriverManager.getConnection(&quot;jdbc:mysql://localhost/?user=root&amp;password=rootpassword&quot;); 
  #PreparedStatement ps = connection.prepareStatement(&quot;CREATE DATABASE databasename&quot;);
  #int result = ps.executeUpdate();
  #spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
  #spring.jpa.hibernate.ddl-auto= update
  # SQL GENERATE CONFIGURATION
  #datasource.schema=  the schema sql script to load. By default it is schema-${platform}.sql then schema.sql;
  #datasource.data= the data sql script. By default, it is data-${platform}.sql then data.sql;
  #spring.h2.console.enabled=true
  #spring.jpa.hibernate.ddl-auto=none
  app.jwt.header=Authorization
  app.jwtSecret= loginSecretKey
  app.jwtExpirationMs= 86400000
  
  </code></pre>
  <p>with a data.sql:</p>
  <pre><code>INSERT INTO roles(name) VALUES('ROLE_USER');
  INSERT INTO roles(name) VALUES('ROLE_MODERATOR');
  INSERT INTO roles(name) VALUES('ROLE_ADMIN');
  
  INSERT INTO users(id, username, email, password) VALUES(777, 'testuser', 'testuser@test.de', '$2a$10$tmPQGqC7XxNmFKwfufGybOxb7HIDA.0lEOtb3ejAiiBn4EfoxI9TK');
  INSERT INTO user_roles(user_id, role_id) VALUES(777, 1);
  INSERT INTO user_roles(user_id, role_id) VALUES(777, 2);
  </code></pre>
  <p>But I can't imagine that H2 is the problem, because the following tests don't fail:</p>
  <pre><code>    @Test
      public void simpleConstructorTestUser() {
          User testUser = new User(&quot;testUser&quot;, &quot;test@test.de&quot;, &quot;testpassword&quot;);
          assertNotNull(testUser.getUsername());
  
      }
  
      @Test
      @PostMapping(&quot;/user&quot;)
      public void userAccess() {
  
          String userName = testUser.getUsername();
          System.out.println(userName);
          Optional&lt;User&gt; userFromDB = userRepository.findByUsername(userName);
          Set&lt;Role&gt; roles = userFromDB.get().getRoles();
  
          for (Role role : roles) {
              String roleType = role.getName().name();
              assertArrayEquals(roleType, &quot;ROLE_USER&quot;);
          }
      }
  </code></pre>
  <p>But maybe I am wrong and it has to do something with H2 instead of MySql?
  For the sake of comprehensiveness: My pom.xml is:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  &lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
      xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;parent&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
          &lt;version&gt;2.3.1.RELEASE&lt;/version&gt;
          &lt;relativePath /&gt; &lt;!-- lookup parent from repository --&gt;
      &lt;/parent&gt;
  
  
      &lt;groupId&gt;com.savetravel&lt;/groupId&gt;
      &lt;artifactId&gt;SaveTravel&lt;/artifactId&gt;
      &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
      &lt;name&gt;SaveTravel&lt;/name&gt;
      &lt;description&gt;TravelApp&lt;/description&gt;
  
  
  
      &lt;properties&gt;
          &lt;java.version&gt;1.8&lt;/java.version&gt;
      &lt;/properties&gt;
  
  
      &lt;dependencies&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;javax.validation&lt;/groupId&gt;
              &lt;artifactId&gt;validation-api&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-data-rest&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
              &lt;scope&gt;runtime&lt;/scope&gt;
              &lt;optional&gt;true&lt;/optional&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
              &lt;artifactId&gt;lombok&lt;/artifactId&gt;
              &lt;scope&gt;provided&lt;/scope&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;com.h2database&lt;/groupId&gt;
              &lt;artifactId&gt;h2&lt;/artifactId&gt;
              &lt;scope&gt;runtime&lt;/scope&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
              &lt;scope&gt;test&lt;/scope&gt;
              &lt;exclusions&gt;
                  &lt;exclusion&gt;
                      &lt;groupId&gt;org.junit.vintage&lt;/groupId&gt;
                      &lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt;
                  &lt;/exclusion&gt;
              &lt;/exclusions&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
              &lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;io.jsonwebtoken&lt;/groupId&gt;
              &lt;artifactId&gt;jjwt&lt;/artifactId&gt;
              &lt;version&gt;0.3&lt;/version&gt;
          &lt;/dependency&gt;
  
      &lt;/dependencies&gt;
  
      &lt;build&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                  &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
              &lt;/plugin&gt;
          &lt;/plugins&gt;
      &lt;/build&gt;
  
  &lt;/project&gt;
  </code></pre>
  <p>Many questions, and the embarassing thing is: I have really no idea WHERE TO SEARCH to solve this problem, especially as the code is supposed to work and a collegue of mine seems to have been able to run it without changes. I would be happy if someone could give me a hint where to start my journey, as I think the Spring security application is terrific and I would love to gain a better understanding of security procedures.
  So if anyone has an idea, such as:</p>
  <ul>
  <li>tests I could write in Spring or Angular to check certain things</li>
  <li>configurations I could look up (I use Linux, maybe that is an Issue?)</li>
  <li>anything else...
  Thanks in advance!
  Tom</li>
  </ul>