Dans le système de gestion backend, le contrôle des autorisations d'accès est généralement requis pour limiter la capacité des différents utilisateurs à accéder à l'interface. Si un utilisateur ne dispose pas d'autorisations spécifiques, il ne peut pas accéder à certaines interfaces.
Cet article utilisera le projet waynboot-mall comme exemple pour présenter comment introduire le cadre de contrôle des autorisations Spring Security dans les systèmes de gestion back-end courants. Le schéma est le suivant :
Adresse du projet waynboot-mall : https://github.com/wayn111/waynboot-mall
Spring Security est un projet open source basé sur le framework Spring, conçu pour fournir des solutions de sécurité puissantes et flexibles pour les applications Java. Spring Security offre les fonctionnalités suivantes :
Introduisez directement la dépendance spring-boot-starter-security dans le projet waynboot-mall,
org.springframework.boot spring-boot-starter-security 3.1.0
La configuration de Spring Security dans Spring Security 3.0 est un peu différente d'avant, par exemple, elle n'hérite plus de WebSecurityConfigurerAdapter. Dans le projet waynboot-mall, la configuration spécifique est la suivante,
@Configuration @EnableWebSecurity @AllArgsConstructor @EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true) public class SecurityConfig { private UserDetailsServiceImpl userDetailsService; private AuthenticationEntryPointImpl unauthorizedHandler; private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; private LogoutSuccessHandlerImpl logoutSuccessHandler; @Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity // cors启用 .cors(httpSecurityCorsConfigurer -> {}) .csrf(AbstractHttpConfigurer::disable) .sessionManagement(httpSecuritySessionManagementConfigurer -> { httpSecuritySessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS); }) .exceptionHandling(httpSecurityExceptionHandlingConfigurer -> { httpSecurityExceptionHandlingConfigurer.authenticationEntryPoint(unauthorizedHandler); }) // 过滤请求 .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> { authorizationManagerRequestMatcherRegistry .requestMatchers("/favicon.ico", "/login", "/favicon.ico", "/actuator/**").anonymous() .requestMatchers("/slider/**").anonymous() .requestMatchers("/captcha/**").anonymous() .requestMatchers("/upload/**").anonymous() .requestMatchers("/common/download**").anonymous() .requestMatchers("/doc.html").anonymous() .requestMatchers("/swagger-ui/**").anonymous() .requestMatchers("/swagger-resources/**").anonymous() .requestMatchers("/webjars/**").anonymous() .requestMatchers("/*/api-docs").anonymous() .requestMatchers("/druid/**").anonymous() .requestMatchers("/elastic/**").anonymous() .requestMatchers("/message/**").anonymous() .requestMatchers("/ws/**").anonymous() // 除上面外的所有请求全部需要鉴权认证 .anyRequest().authenticated(); }) .headers(httpSecurityHeadersConfigurer -> { httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable); }); // 处理跨域请求中的Preflight请求(cors),设置corsConfigurationSource后无需使用 // .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() // 对于登录login 验证码captchaImage 允许匿名访问 httpSecurity.logout(httpSecurityLogoutConfigurer -> { httpSecurityLogoutConfigurer.logoutUrl("/logout"); httpSecurityLogoutConfigurer.logoutSuccessHandler(logoutSuccessHandler); }); // 添加JWT filter httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); // 认证用户时用户信息加载配置,注入springAuthUserService httpSecurity.userDetailsService(userDetailsService); return httpSecurity.build(); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } /** * 强散列哈希加密实现 */ @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } }
Voici une introduction détaillée à la classe de configuration SecurityConfig :
Pour utiliser Spring Security, il vous suffit d'ajouter l'annotation @PreAuthorize correspondante sur la méthode ou la classe qui doit contrôler les autorisations d'accès, comme suit,
@Slf4j @RestController @AllArgsConstructor @RequestMapping("system/role") public class RoleController extends BaseController { private IRoleService iRoleService; @PreAuthorize("@ss.hasPermi('system:role:list')") @GetMapping("/list") public R list(Role role) { Page page = getPage(); return R.success().add("page", iRoleService.listPage(page, role)); } }
Nous avons ajouté l'annotation @PreAuthorize(“@ss.hasPermi('system:role:list')”) à la méthode list pour indiquer que l'utilisateur actuellement connecté dispose des autorisations system:role:list pour accéder à la méthode list, sinon une erreur d'autorisation sera renvoyée.
Dans la classe de configuration SecurityConfig, nous définissons UserDetailsServiceImpl comme notre classe d'implémentation pour charger les informations utilisateur, afin de comparer le compte et le mot de passe de l'utilisateur dans la base de données avec le compte et le mot de passe transmis par le front-end. Le code est le suivant,
@Slf4j @Service @AllArgsConstructor public class UserDetailsServiceImpl implements UserDetailsService { private IUserService iUserService; private IDeptService iDeptService; private PermissionService permissionService; public static void main(String[] args) { BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); System.out.println(bCryptPasswordEncoder.encode("123456")); } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 1. 读取数据库中当前用户信息 User user = iUserService.getOne(new QueryWrapper().eq("user_name", username)); // 2. 判断该用户是否存在 if (user == null) { log.info("登录用户:{} 不存在.", username); throw new UsernameNotFoundException("登录用户:" + username + " 不存在"); } // 3. 判断是否禁用 if (Objects.equals(UserStatusEnum.DISABLE.getCode(), user.getUserStatus())) { log.info("登录用户:{} 已经被停用.", username); throw new DisabledException("登录用户:" + username + " 不存在"); } user.setDept(iDeptService.getById(user.getDeptId())); // 4. 获取当前用户的角色信息 Set rolePermission = permissionService.getRolePermission(user); // 5. 根据角色获取权限信息 Set menuPermission = permissionService.getMenuPermission(rolePermission); return new LoginUserDetail(user, menuPermission); } }
Voici une explication de la logique du code de UserDetailsServiceImpl, afin que vous puissiez la comprendre à l'aide du code.
Cet article vous explique comment introduire la version Spring Security 3.0 du framework de contrôle des autorisations dans le système de gestion back-end et la pratique du code. Je pense que cela peut aider tout le monde à avoir une compréhension claire du cadre de contrôle des autorisations Spring Security. Plus tard, vous pourrez suivre le guide d'utilisation de cet article pour introduire étape par étape Spring Security dans vos propres projets pour le contrôle d'accès.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!