繁体   English   中英

hasRole(“ROLE_USER”)在 spring boot3 和 springsecurity6 中不工作

[英]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.

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