spring 安全 HTTP 状态 403 - 拒绝访问
spring security HTTP Status 403 - Access Denied
登录成功但 spring 安全阻止 url 即使我授予了 USER 的访问权限。我该如何管理这件事?
@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/欢迎.
2.重定向到URL后localhost:8080/sales是不是403 Access denied.
什么是spring安全
Spring 安全是关于身份验证和授权的,在您的情况下您缺少身份验证。您的安全配置中没有配置身份验证。您缺少的是 spring 安全性的身份验证过滤器。 Spring 安全性提供默认身份验证过滤器 UsernamePasswordAuthenticationFilter
,可以通过 .formLogin()
配置。您可以使用提供的默认值,也可以定义自己的自定义身份验证过滤器(UsernamePasswordAuthenticationFilter
的实现)。
身份验证成功后spring 安全性将为经过身份验证的用户授予权限。如果认证配置正确,下面的配置负责认证和授权
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()
没有任何配置提供带有用户名和密码默认形式的默认登录页面 parameters.And 身份验证后它重定向到 "/"
如果你想提供自定义登录页面然后使用下面配置。
.and().formLogin()
.loginPage("/login")
.usernameParameter("email").passwordParameter("password")
.defaultSuccessUrl("/app/user/dashboard")
.failureUrl("/login?error=true")
.loginPage("")
- 您的自定义登录页面 URL
.usernameParameter("").passwordParameter("")
- 您的自定义登录表单参数
.defaultSuccessUrl("")
- 页面 url 成功验证后
.failureUrl("")
- 页面 url 认证失败后
注意:你不应该在你的控制器中使用“/login”POST方法,即使你写了,它也不会从spring安全过滤器链到达.由于你之前的配置不对,所以是reaching before!现在你从你的控制器中删除它们并使用上面提到的传统方法。
登录成功但 spring 安全阻止 url 即使我授予了 USER 的访问权限。我该如何管理这件事?
@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/欢迎.
2.重定向到URL后localhost:8080/sales是不是403 Access denied.
什么是spring安全
Spring 安全是关于身份验证和授权的,在您的情况下您缺少身份验证。您的安全配置中没有配置身份验证。您缺少的是 spring 安全性的身份验证过滤器。 Spring 安全性提供默认身份验证过滤器 UsernamePasswordAuthenticationFilter
,可以通过 .formLogin()
配置。您可以使用提供的默认值,也可以定义自己的自定义身份验证过滤器(UsernamePasswordAuthenticationFilter
的实现)。
身份验证成功后spring 安全性将为经过身份验证的用户授予权限。如果认证配置正确,下面的配置负责认证和授权
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()
没有任何配置提供带有用户名和密码默认形式的默认登录页面 parameters.And 身份验证后它重定向到 "/"
如果你想提供自定义登录页面然后使用下面配置。
.and().formLogin()
.loginPage("/login")
.usernameParameter("email").passwordParameter("password")
.defaultSuccessUrl("/app/user/dashboard")
.failureUrl("/login?error=true")
.loginPage("")
- 您的自定义登录页面 URL
.usernameParameter("").passwordParameter("")
- 您的自定义登录表单参数
.defaultSuccessUrl("")
- 页面 url 成功验证后
.failureUrl("")
- 页面 url 认证失败后
注意:你不应该在你的控制器中使用“/login”POST方法,即使你写了,它也不会从spring安全过滤器链到达.由于你之前的配置不对,所以是reaching before!现在你从你的控制器中删除它们并使用上面提到的传统方法。