简体   繁体   中英

spring security HTTP Status 403 - Access Denied

Login is success but spring security blocking url even i given access to USER . How can i manage this thing?

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.inMemoryAuthentication().withUser("sahil").password("123")
                .roles("ADMIN","USER");
    }

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

        http.authorizeRequests()
        .antMatchers("/login").permitAll()
        .antMatchers("/welcome","/inventory/**","/sales/**").access("hasRole('USER')")
        .and()
        .csrf().disable();
    }

LoginController.java

    @Controller
public class LoginController {

    @RequestMapping(value = { "/", "/login" }, method = RequestMethod.GET)
    public String showLoginPage() {
        return "login";
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String handleUserLogin(ModelMap model, @RequestParam String name, @RequestParam String password) {
        if (!service.validateUser(name, password)) {
            model.put("errorMsg", "Invalid Credential");
            return "login";
        }
        System.out.println("principal : " + getLoggedInUserName());
        model.put("name", name);
        model.put("password", password);
        return "welcome";
    }

    private String getLoggedInUserName() {

        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        if (principal instanceof UserDetails) {
            System.out.println("in if");
          return  ((UserDetails)principal).getUsername();

        } else {
            System.out.println("in else");
         return principal.toString();

        }
    }

    @RequestMapping(value = "/welcome", method = RequestMethod.GET)
    public String showWelcomeDashboard() {
        return "welcome";
    }
}

1. Once Login success page redirected to welcome page but url is still localhost:8080/login instead of localhost:8080/welcome .

欢迎仪表板

2. After redirecting to URL localhost:8080/sales is it 403 Access denied.

销售页面

What is spring security
Spring security is all about authentication and authorization, in your case you are missing authentication. There is no configuration of authentication in your security configuration. What you are missing is authentication filter for your spring security. Spring security provides default authentication filter UsernamePasswordAuthenticationFilter that can be configured by .formLogin() . You can use default provided or you can define your own custom authentication filter(Implementation of UsernamePasswordAuthenticationFilter ).

Once authentication is success spring security will grant authorities for authenticated user. If authentication is configured correctly, below configuration is responsible for authentication and granting authority

auth.inMemoryAuthentication().withUser("sahil").password("123")
                .roles("ADMIN","USER");

Authenticated users each request will be passed through filter FilterSecurityInterceptor and it will verifies authority granted for authenticated user with authorization configured for resources as given in below code.

.antMatchers("/welcome","/inventory/**","/sales/**").access("hasRole('USER')")

You missed all this by not configuring authentication filter.
Now for making it simple use.formLogin() in your http configuration.

@Override
protected void configure(final HttpSecurity http) throws Exception
{
    http
    .authorizeRequests()
        .antMatchers("/welcome","/inventory/**","/sales/**").access("hasRole('USER')")
    .and().exceptionHandling()
        .accessDeniedPage("/403")
    .and().formLogin()
    .and().logout()
        .logoutSuccessUrl("/login?logout=true")
        .invalidateHttpSession(true)
    .and()
        .csrf()
            .disable();
}

.formLogin() without any configuration provides default login page with username and password default form parameters.And after authentication it redirects to "/" If you want to provide your custom login page then use below configuration.

.and().formLogin()
       .loginPage("/login")
       .usernameParameter("email").passwordParameter("password")
       .defaultSuccessUrl("/app/user/dashboard")
       .failureUrl("/login?error=true")

.loginPage("") - Your custom login page URL
.usernameParameter("").passwordParameter("") - Your custom login form parameters
.defaultSuccessUrl("") - Page url after successful authentication
.failureUrl("") - Page url after authentication failure

Note: You should not use "/login" POST method in your controller, Even though if you write, it will not be reached from spring security filter chain. As your configuration was wrong before, it was reaching before. Now you remove those from your controller and use conventional approach as mentioned above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM