基于Spring Security前后端分离的权限控制系统是一个非常常见的开发需求。下面将提供完整攻略,从搭建环境、配置安全策略、实现权限控制等方面讲解该系统的具体实现。其中示例将分别展示两种不同的权限控制方式。
1. 搭建环境
首先,需要搭建一个Spring Boot项目,并且集成Spring Security。需要在项目中引入以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
然后,在Spring Security配置类中进行基础配置即可:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasRole("USER")
.anyRequest().authenticated()
.and().csrf().disable();
}
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("admin").roles("ADMIN")
.and()
.withUser("user").password("user").roles("USER");
}
}
以上示例中,我们限制了访问/admin/路径的用户必须拥有ADMIN角色,/user/路径的用户必须拥有USER角色;我们同时也对所有的请求进行了验证,要求用户先进行身份认证。其中,configureGlobal方法指定了内存中的用户信息。
2. 安全策略配置
接下来,我们将介绍如何配置更加复杂的安全策略。以下示例中,我们将分别展示两种不同的权限控制方式:基于角色的访问控制和基于权限的访问控制。
2.1 基于角色的访问控制
基于角色的访问控制是最为基础的安全策略,这种安全策略可以直接映射到用户所对应的角色上。下面是一个具体的示例:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Bean
public JwtAuthenticationFilter authenticationJwtTokenFilter() {
return new JwtAuthenticationFilter(jwtTokenProvider, customUserDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/test/**").hasRole("USER")
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
以上示例中,我们限制了用户访问/api/test/路径的用户必须拥有USER角色,同时开放了/api/auth/路径用于用户登录。我们并且关闭了csrf防护和开启了CORS,以允许跨域访问。
2.2 基于权限的访问控制
基于权限的访问控制是一种更为细粒度的权限控制方式。实现方法也较为简单,只需要在代码中针对每个URL进行访问控制即可。下面是一个具体的示例:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Bean
public JwtAuthenticationFilter authenticationJwtTokenFilter() {
return new JwtAuthenticationFilter(jwtTokenProvider, customUserDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/test/regular/**").hasAnyAuthority("READ_REGULAR")
.antMatchers("/api/test/sensitive/**").hasAnyAuthority("READ_SENSITIVE")
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
以上示例中,我们限制了用户访问/api/test/regular/路径的用户必须拥有READ_REGULAR权限,/api/test/sensitive/路径的用户必须拥有READ_SENSITIVE权限。这种安全策略需要先定义好各种权限,再将每个URL对应到相应的权限上。
3. 实现权限控制
最后,我们需要详细实现权限控制,在代码中实现访问控制。这里我们介绍两种实现方式:
3.1 基于注解的权限控制
基于注解的权限控制是一种简单直接的实现方式。只需要在需要进行权限控制的方法上添加注解,就可以进行权限控制。下面是一个具体的示例:
@RestController
@RequestMapping("/api/test")
public class TestController {
@GetMapping("/regular")
@PreAuthorize("hasAnyAuthority('READ_REGULAR')")
public ResponseEntity<String> getRegularData() {
return ResponseEntity.ok("Regular data retrieved!");
}
@GetMapping("/sensitive")
@PreAuthorize("hasAnyAuthority('READ_SENSITIVE')")
public ResponseEntity<String> getSensitiveData() {
return ResponseEntity.ok("Sensitive data retrieved!");
}
}
以上示例中,我们使用了@PreAuthorize注解限定了getRegularData和getSensitiveData方法需要具备相应的权限才能访问。
3.2 基于URL拦截的权限控制
基于URL拦截的权限控制是一种更为灵活的实现方式。需要在代码中检查用户所拥有的权限与访问URL的所需要的权限是否匹配。下面是一个具体的示例:
@Service
public class AuthorizationService {
public boolean canUserAccessURL(HttpServletRequest request) {
// 获取用户信息
User user = getUserFromRequest(request);
// 根据当前URL获取所需要的权限
String url = request.getRequestURI();
List<String> requiredAuthorityList = getRequiredAuthorityList(url);
// 判断用户是否拥有所需权限
return user.getAuthorities().stream().anyMatch(u -> requiredAuthorityList.contains(u.getAuthority()));
}
private User getUserFromRequest(HttpServletRequest request) {
// 从请求中获取用户信息
return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
private List<String> getRequiredAuthorityList(String url) {
// 从权限控制规则中获取所需权限
List<String> requiredAuthorityList = new ArrayList<>();
if (url.contains("/regular")) {
requiredAuthorityList.add("READ_REGULAR");
}
if (url.contains("/sensitive")) {
requiredAuthorityList.add("READ_SENSITIVE");
}
return requiredAuthorityList;
}
}
以上示例中,我们定义了一个AuthorizationService类,其中的canUserAccessURL方法用于检查用户是否有访问所需URL的权限。在每个请求到达Controller的时候,都可以通过这个AuthorizationService类进行权限检查。
以上就是“基于Spring Security前后端分离的权限控制系统问题”的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于Spring Security前后端分离的权限控制系统问题 - Python技术站