Search code examples
spring-securityspring-el

Spring Security permitting access only to own ressources


I am trying to limit the api access only to own ressources. Sadly it doesn't work. At the moment I can access every user Data at 'users/{userid}'. So if my userid is 10, i also can access the data of 11 by replacing userid.

SecurityConig.java

@SuppressWarnings("SpringJavaAutowiringInspection")
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Autowired
    private JwtAuthenticationProvider jwtAuthenticationProvider;

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) {
        authenticationManagerBuilder.authenticationProvider(jwtAuthenticationProvider);
    }

    @Bean
    public JwtAuthenticationTokenFilter authenticationTokenFilterBean() {
        return new JwtAuthenticationTokenFilter();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .csrf().disable()
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/users").permitAll()
                .antMatchers("/user/{userid}/**")
                    .access("@userSecurity.hasUserId(authentication,#userid)")
                .anyRequest().authenticated();

        httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
        httpSecurity.headers().cacheControl();
    }

For limiting access I use Spring EL expressions. IntelliJ show me 'Can not resolve variable 'userid'

 .antMatchers("/user/{userid}/**")
                    .access("@userSecurity.hasUserId(authentication,#userid)")

This is my UserSecurity.java


   public class UserSecurity  {

    private final JwtTokenService jwtService;

    @SuppressWarnings("unused")
    public UserSecurity() {
        this(null);
    }
    public UserSecurity(JwtTokenService jwtService) {
        this.jwtService = jwtService;
    }

    public boolean hasUserId(Authentication authentication, String userid) {
        String token = (String) authentication.getCredentials();
        String username = jwtService.getUsernameFromToken(token);
        return username.equals(userid);

    }
}

I also found out, that if i replace the '#userid' with a string, it doesn't work. It doesn't go into the method,


Solution

  • Found my mistake.

    this

    .antMatchers("/user/{userid}/**")
                        .access("@userSecurity.hasUserId(authentication,#userid)")
    
    

    should be this

    .antMatchers("/users/{userid}/**")
                        .access("@userSecurity.hasUserId(authentication,#userid)")
    
    

    had a mistake on the path name.