在罕用的后盾管理系统中,通常都会有拜访权限管制的需要,用于限度不同人员对于接口的拜访能力,如果用户不具备指定的权限,则不能拜访某些接口。
本文将用 waynboot-mall 我的项目举例,给大家介绍常见后管零碎如何引入权限管制框架 Spring Security。纲要如下,
一、什么是 Spring Security
Spring Security 是一个基于 Spring 框架的开源我的项目,旨在为 Java 应用程序提供弱小和灵便的安全性解决方案。Spring Security 提供了以下个性:
- 认证:反对多种认证机制,如表单登录、HTTP 根本认证、OAuth2、OpenID 等。
- 受权:反对基于角色或权限的访问控制,以及基于表达式的细粒度管制。
- 防护:提供了多种防护措施,如避免会话固定、点击劫持、跨站申请伪造等攻打。
- 集成:与 Spring 框架和其余第三方库和框架进行无缝集成,如 Spring MVC、Thymeleaf、Hibernate 等。
二、如何引入 Spring Security
在 waynboot-mall 我的项目中间接引入 spring-boot-starter-security 依赖,
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>3.1.0</version> </dependency></dependencies>
三、如何配置 Spring Security
在 Spring Security 3.0 中要配置 Spring Security 跟以往是有些不同的,比方不在继承 WebSecurityConfigurerAdapter。在 waynboot-mall 我的项目中,具体配置如下,
@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(); }}
这里具体介绍下 SecurityConfig 配置类,
- filterChain(HttpSecurity httpSecurity) 办法是访问控制的外围办法,这外面能够针对 url 设置是否须要权限认证、cors 配置、csrf 配置、用户信息加载配置、jwt 过滤器拦挡配置等泛滥性能。
- authenticationManager(AuthenticationConfiguration authenticationConfiguration) 办法实用于启用认证接口,须要手动申明,否则启动报错。
- bCryptPasswordEncoder() 办法用户定义用户登录时的明码加密策略,须要手动申明,否则启动报错。
四、如何应用 Spring Security
要应用 Spring Security,只须要在须要管制拜访权限的办法或类上增加相应的 @PreAuthorize 注解即可,如下,
@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<Role> page = getPage(); return R.success().add("page", iRoleService.listPage(page, role)); }}
咱们在 list 办法上加了 @PreAuthorize("@ss.hasPermi('system:role:list')")
注解示意以后登录用户领有 system:role:list 权限能力拜访 list 办法,否则返回权限谬误。
五、获取以后登录用户权限
在 SecurityConfig 配置类中咱们定义了 UserDetailsServiceImpl 作为咱们的用户信息加载的实现类,从而通过读取数据库中用户的账号、明码与前端传入的账号、明码进行比对。代码如下,
@Slf4j@Service@AllArgsConstructorpublic 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<User>().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<String> rolePermission = permissionService.getRolePermission(user); // 5. 依据角色获取权限信息 Set<String> menuPermission = permissionService.getMenuPermission(rolePermission); return new LoginUserDetail(user, menuPermission); }}
针对 UserDetailsServiceImpl 的代码逻辑进行一个解说,大家能够配合代码了解。
- 读取数据库中以后用户信息
- 判断该用户是否存在
- 判断是否禁用
- 获取以后用户的角色信息
- 依据角色获取权限信息
总结一下
本文给大家解说了后管零碎如何引入权限管制框架 Spring Security 3.0 版本以及代码实战。置信能帮忙大家对权限管制框架 Spring Security 有一个清晰的了解。后续大家能够依照本文的使用指南一步一步将 Spring Security 引入到的本人的我的项目中用于拜访权限管制。
想要获取 waynboot-mall 我的项目源码的同学,能够关注我公众号【程序员wayn】,回复 waynboot-mall 即可取得。
如果感觉这篇文章写的不错的话,无妨点赞加关注,我会更新更多技术干货、我的项目教学、实战经验分享的文章。