文章目录
- 一、基于权限的请求控制
- 二、加载用户权限信息
- 三、自定义异常处理
- 四、注册自定义异常处理器
- 五、总结
在开发Web应用时,权限管理是一个不可忽视的部分。最近在项目中,我使用了Spring Security来实现用户、权限、资源之间的精细化控制。这里我想分享一下我的经验,希望对大家有所帮助。
一、基于权限的请求控制
首先,我们需要根据不同的资源路径设置相应的权限要求。以下是我的配置代码:
http.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/user/list").hasAuthority("USER_LIST")
.requestMatchers("/user/add").hasAuthority("USER_ADD")
// 对所有请求开启授权保护
.anyRequest()
// 已认证请求会自动被授权
.authenticated());
这段代码的含义是:
- 访问
/user/list
的请求需要拥有USER_LIST
权限。 - 访问
/user/add
的请求需要拥有USER_ADD
权限。 - 其他所有请求都需要用户已认证(登录)。
通过这种方式,我们实现了资源路径与权限的直接绑定,确保只有具备特定权限的用户才能访问对应的资源。
二、加载用户权限信息
接下来,我们需要为用户加载其对应的权限信息。在Spring Security中,我们可以通过实现UserDetailsService
接口来完成:
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(User::getUsername, username);
User user = userMapper.selectOne(lambdaQueryWrapper);
if (user == null) {
throw new UsernameNotFoundException(username);
} else {
Collection<GrantedAuthority> authorities = new ArrayList<>();
// 模拟为用户添加权限,实际项目中应从数据库获取用户的权限列表
// authorities.add(() -> "USER_LIST");
authorities.add(() -> "USER_ADD");
return new org.springframework.security.core.userdetails
.User(user.getUsername(), user.getPassword(),
user.getEnabled(),
// 用户账号是否未过期
true,
// 用户凭证是否未过期
true,
// 用户是否未被锁定
true,
// 用户的权限列表
authorities);
}
}
在这个方法中,我们:
- 根据用户名从数据库中查询用户信息。
- 如果用户存在,创建一个权限列表
authorities
。 - 为用户分配对应的权限(在实际应用中,应从数据库中获取用户的权限列表)。
- 返回一个包含用户名、密码、权限等信息的
UserDetails
对象。
通过这种方式,我们实现了用户与权限的关联,为后续的权限验证提供了基础。
三、自定义异常处理
当用户尝试访问未被授权的资源时,默认情况下会跳转到一个错误页面。为了提升用户体验,我们希望返回一个JSON格式的错误信息。这就需要自定义AccessDeniedHandler
:
public class MyAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
// 创建结果对象
HashMap<String, Object> result = new HashMap<>();
result.put("code", -1);
result.put("message", "没有权限");
// 转换成JSON字符串
String json = JSON.toJSONString(result);
// 返回响应
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(json);
}
}
这样,当用户没有权限访问某个资源时,会返回一个包含错误代码和提示信息的JSON对象,方便前端进行处理。
四、注册自定义异常处理器
最后,我们需要在Spring Security的配置中注册我们自定义的异常处理器:
http.exceptionHandling(exception -> {
// 请求未认证的处理
exception.authenticationEntryPoint(new MyAuthenticationEntryPoint());
// 请求未授权的处理
exception.accessDeniedHandler(new MyAccessDeniedHandler());
});
通过上述配置,Spring Security会在遇到认证或授权异常时,调用我们自定义的处理器,从而返回统一的错误信息。
五、总结
通过以上步骤,我们实现了用户、权限、资源之间的精细化控制:
- 用户:通过
UserDetailsService
加载用户信息和权限。 - 权限:为用户分配特定的权限标识符,如
USER_LIST
、USER_ADD
。 - 资源:通过
requestMatchers
指定资源路径,并绑定所需的权限。
这种用户-权限-资源的控制方式,能够有效地保障系统的安全性,确保只有具备相应权限的用户才能访问特定的资源。