春季安全性HTTP状态403-拒绝访问

时间:2019-09-25 12:39:30

标签: java spring spring-mvc spring-security access-denied

登录是成功的,但是即使我授予了 USER 的访问权限,Spring安全性也会阻止url。我该如何管理这个东西?

@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。一旦登录成功页面重定向到欢迎页面,但URL仍然是 localhost:8080 / login 而不是 localhost:8080 / welcome

welcome dashboard

2。。重定向到URL localhost:8080 / sales 后,是否拒绝403访问。

sales page

1 个答案:

答案 0 :(得分:2)

什么是弹簧安全性
Spring安全性完全与身份验证和授权有关,在这种情况下,您将缺少身份验证。安全配置中没有身份验证配置。您缺少的是用于弹簧安全性的身份验证过滤器。 Spring Security提供了可以由UsernamePasswordAuthenticationFilter配置的默认身份验证过滤器.formLogin()。您可以使用提供的默认值,也可以定义自己的自定义身份验证过滤器(UsernamePasswordAuthenticationFilter的实现)。

一旦身份验证成功,Spring Security将为已身份验证的用户授予权限。如果身份验证配置正确,则下面的配置负责身份验证和授予权限

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

经过身份验证的用户,每个请求将通过过滤器FilterSecurityInterceptor,它将验证为身份验证的用户授予的权限,该权限具有为以下代码中指定的资源配置的权限。

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

您没有配置身份验证过滤器而错过了所有这一切。
现在,在您的http配置中使其变得简单use.formLogin()。

@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()(不进行任何配置)会提供具有用户名和密码默认表单参数的默认登录页面。身份验证后,它会重定向到"/",如果要提供自定义登录页面,则使用以下配置。

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

.usernameParameter("").passwordParameter("")-您的自定义登录页面URL
.defaultSuccessUrl("")-您的自定义登录表单参数
.failureUrl("")-成功认证后的页面网址
$ExtractText = $crawler->filter('strong')->eq(1)->text(); -身份验证失败后的页面网址

注意:您不应该在控制器中使用“ / login” POST方法,即使您编写了它,也不会从Spring安全过滤器链中获得。由于您之前的配置是错误的,因此之前达到了!现在,将它们从控制器中删除,并使用上述常规方法。