[英]hasRole("ROLE_USER") not working in spring boot3 with springsecurity6
提示:本站为国内最大中英文翻译问答网站,提供中英文对照查看,鼠标放在中文字句上可显示英文原文。
我在 spring 引导中创建了一个 LoginFilter,我在其中创建了用户身份验证 object,然后重定向到仪表板页面
我的以下文件是:
登录过滤器.java
import jakarta.servlet.*;
/*import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;*/
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.GenericFilterBean;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;
@Component
public class LoginFilter extends GenericFilterBean {
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,ServletException
{
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
List<SimpleGrantedAuthority> updatedAuthorities = new ArrayList<SimpleGrantedAuthority>();
updatedAuthorities.add(authority);
authentication = new UsernamePasswordAuthenticationToken("myemail.gamil.com", null, updatedAuthoritie
SecurityContextHolder.getContext().setAuthentication(authentication);
this.redirectStrategy.sendRedirect((HttpServletRequest) request, (HttpServletResponse) response,"/dashboard");
}
}
WebSecurityConfigDashboard.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
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.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
public class WebSecurityConfigDashboard {
@Autowired
private LoginFilter loginFilter;
@Bean
//authentication
public UserDetailsService userDetailsService1(PasswordEncoder encoder) {
UserDetails admin = User.withUsername("user1")
.password(encoder.encode("123"))
.roles("ROLE_USER")
.build();
UserDetails user = User.withUsername("user2")
.password(encoder.encode("123"))
.roles("ROLE_USER")
.build();
return new InMemoryUserDetailsManager(admin, user);
}
@Bean
public SecurityFilterChain securityFilterChain1(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeHttpRequests()
.requestMatchers("/dashboard*").hasRole("ROLE_USER")
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.failureUrl("/loginError")
.and().logout()
.invalidateHttpSession(true)
.logoutSuccessUrl("/logout")
.logoutUrl("/j_spring_security_logout").and()
.sessionManagement()
.maximumSessions(12)
.expiredUrl("/logout");
http.addFilterAfter(loginFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer1() {
return (web) -> web.ignoring().requestMatchers("/resources/images/**");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
登录控制器.java
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.*;
@Controller
public class LoginController {
@RequestMapping(value = "/dashboard")
public String dashboard(Model model,Principal principal,HttpServletRequest request, HttpServletResponse response)
{
System.out.println("/dashboard called:------------------------>");
System.out.println("PRINCIPAL:--------------->"+principal.getName());
return 'dashboard';
}
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(ModelMap model) {
System.out.println("/login called:------------------------>");
return "login";
}
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logout(ModelMap model) {
System.out.println("/logout called:------------------------>");
return "logout";
}
@RequestMapping(value = "/loginError", method = RequestMethod.GET)
public String loginError(ModelMap model) {
model.addAttribute("error", "LOGIN FAILED");
return "login";
}
@RequestMapping(value = "/error", method = RequestMethod.GET)
public String error(ModelMap model,HttpServletRequest request, HttpServletResponse response) {
return "error";
}
}
当我在浏览器中调用 /dashboard url 时,它会转到登录页面而不是仪表板我在过滤器 class 中创建了 UsernamePasswordAuthenticationToken。
如果我删除.hasRole("ROLE_USER")而不是放.permitAll()然后如果我点击 /dashboard 然后调用 /dashboard 的方法但是原理 object 得到 null
我使用 spring boot 3 和 spring security 6
我不知道为什么会这样?
一个常见的疏忽是roles()
和hasRole()
将为您添加ROLE_
前缀。
所以,不要做hasRole('ROLE_USER')
,请做hasRole('USER')
。 而不是在创建用户时执行roles('ROLE_USER')
,而是执行roles('USER')
。
我添加了一张 Spring 安全票来澄清这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.