1

I'm writing a basic Web App using Java Spring Boot and am currently having issues with the roles of my users in my database and access to different parts of the app. The users can either have the role "ADMIN" or "USER". The only difference between what's allowed for these 2 roles is that the ADMIN is able to visit the "/register" page, whereas the other people in the role USER cannot. I have posted the code for my http configure method below, and am not sure where I am going wrong. I want all users to be able to access the login page and only the ADMIN to access the "/register" page. The issue I'm experiencing is that as of now, for some reason, the "/home" page to my app is to able be seen without even logging in. Logging in with what I have below is not being enforced.

package bcoreHW.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.password.PasswordEncoder;

import bcoreHW.service.UserService;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers( // allow users access to any files in js, css, and img directories
                    "/login",
                    "/js/**",
                    "/css/**",
                    "/img/**")
                .permitAll()
                .antMatchers("/register")
                .hasRole("ADMIN")
                .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/home")
                .permitAll()
                .and()
            .logout()
                .permitAll();
        }

//  @Autowired
//  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//      auth
//          .inMemoryAuthentication()
//          .withUser("test")
//          .password("hello")
//          .roles("USER");
//      }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder);
    }
}

If I change the configure() method to what I have below, however, at least the user is forced to login, and the permissions from there are correct on an "on-click" basis, but I am still able to go to the address bar and search for "/register" under a USER role, which is why I attempted to implement the first piece of code I posted. Neither have worked yet, and was hoping for some help.

package bcoreHW.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.password.PasswordEncoder;

import bcoreHW.service.UserService;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //@formatter:off
        http
            .authorizeRequests()
                .antMatchers( // allow users access to any files in js, css, and img directories
                    "/login",
                    "/js/**",
                    "/css/**",
                    "/img/**")
                .permitAll()
            .anyRequest().
                authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/home")
                .permitAll()
                .and()
            .logout()
                .permitAll();
        }

//  @Autowired
//  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//      auth
//          .inMemoryAuthentication()
//          .withUser("test")
//          .password("hello")
//          .roles("USER");
//      }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder);
    }
}

CDA the Programmer
  • 87
  • 1
  • 6
  • 20

1 Answers1

1

Make sure you are storing the users with roles as ROLE_ADMIN and ROLE_USER in the database

 @Override
    public void configure(HttpSecurity http) throws Exception {

        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers( "/login", "/js/**", "/css/**", "/img/**").permitAll() // allow users access to any files in js, css, and img directories
            .antMatchers("/register").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin().loginPage("/login")
            .defaultSuccessUrl("/home").permitAll()
            .and()
            .logout().permitAll();
}
Romil Patel
  • 12,879
  • 7
  • 47
  • 76
  • Adding in .csrf().disable() didn't fix the issue of allowing any user to go directly to the home page without authorization. I also have the following method in my page controllers, which could be interfering. ```@RequestMapping(value= {"/home", "/"}, method=RequestMethod.GET) ModelAndView viewRecord(ModelAndView modelAndView, @RequestParam(name="p", defaultValue="1") int pageNumber) { Page page = newRecordService.getPage(pageNumber); modelAndView.getModel().put("page", page); modelAndView.setViewName("app.home");return modelAndView; }``` – CDA the Programmer Jun 16 '20 at 15:39
  • And, yes, the roles in the DB are set to ROLE_ADMIN and ROLE_USER. You can see in the method above that the default page request is supposed to take the user to the "app.home" page, but this should all be preceded by forcing the user to login, no? – CDA the Programmer Jun 16 '20 at 15:43
  • 1
    Hello, If home page should be accessed after the login, you may remove `/` the from *viewRecord* any may add to your custom login method as `{"/login", "/"}`. – Romil Patel Jun 16 '20 at 15:51
  • 1
    If you want home page to be accessed without authentication you may use `.antMatchers( "/home").permitAll()` – Romil Patel Jun 16 '20 at 15:53
  • Just to summarize and make sure we are clear: the only page I want to be accessible until login by any user is "/login". So, essentially I want "/" to default to "/login". With what I currently have, what would I have to change there? – CDA the Programmer Jun 16 '20 at 16:15
  • 1
    You may remove `/` from *viewRecord* method as the same will get invoked as default mapping if no other mapping has matched any will result in 401/403. Let me know if you face any issue after the changes. – Romil Patel Jun 16 '20 at 16:26
  • And in configure() do I want to have "/" in addition to what I have here? ```@Override protected void configure(HttpSecurity http) throws Exception { //@formatter:off http .authorizeRequests() .antMatchers( "/login", "/js/**", "/css/**", "/img/**").permitAll() .antMatchers("/register").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin().loginPage("/login") .defaultSuccessUrl("/home").permitAll() .and() .logout().permitAll(); }``` – CDA the Programmer Jun 16 '20 at 16:37
  • 1
    I was getting 404 error so I had to add in the following to catch everything, and so it seems to all be working now. Thanks very much for your help and quick responses! ``` @RequestMapping("/") String login() { return "app.login"; }``` – CDA the Programmer Jun 16 '20 at 16:53