如何利用@PreAuthorize注解自定义权限校验
作者:Slavic_
通过使用@PreAuthorize注解实现开放接口的权限校验,具体步骤包括开启全局方法安全、编写自定义鉴权方法、创建自定义异常类、在统一异常处理类中捕获异常并处理,最后在需要鉴权的接口上贴上注解
利用@PreAuthorize注解自定义权限校验
使用场景
由于项目中,需要对外开放接口,要求做请求头校验,不做其他权限控制.所以准备对开放的接口全部放行,不做登录校验.想到之前用这个注解来实现管理后台的权限校验,所以为了方便在需要对外开放的接口贴上注解即可.记录一下实现过程.
1.开启@EnableGlobalMethodSecurity(prePostEnabled = true)注解
在继承 WebSecurityConfigurerAdapter 这个类的类上面贴上这个注解.并且prePostEnabled设置为true,@PreAuthorize这个注解才能生效,SpringSecurity默认是关闭注解功能的。
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {....}
2.编写自定义的鉴权方法
// service取名sc是方便注解调用 @Service("sc") @Slf4j public class SginCheckService { @Autowired private PlatformManageService platformManageService; public boolean checkSgin(){ HttpServletRequest request = UserContextHolder.getHttpServletRequest(); String appid = request.getHeader("appid"); String signature = request.getHeader("signature"); String timestamp = request.getHeader("timestamp"); //非crm管理平台 PlatformManage platformManage = platformManageService.getOne(Wrappers.<PlatformManage>lambdaQuery().eq(PlatformManage::getSourcetype, appid)); if (platformManage == null) { log.error("平台不存在:" + appid); //鉴权失败抛出自定义异常 throw new SginCheckException(); } //校验签名 String secretKey = platformManage.getPrivateKey(); MD5 md5 = new MD5(); String lowerCase = md5.getMD5ofStr(appid + secretKey + timestamp).toLowerCase(); if (!lowerCase.equals(signature)) { log.error("签名校验失败:" + "crm:" + lowerCase + ",接口:" + signature); //鉴权失败抛出自定义异常 throw new SginCheckException(); } //如果鉴权成功不return true 会报错. return true; } }
3.创建自定义异常类
public class SginCheckException extends BaseException { public SginCheckException() { super(); } public SginCheckException(String message) { super(SystemErrorType.SIGNATURE_ERROR,message); } }
4.在统一异常处理类里面捕获异常类并做对应处理
@ControllerAdvice @Slf4j public class GlobalExceptionHandler { /** * 签名失败抛出异常处理 * * @param e * @return */ @ResponseBody @ResponseStatus(HttpStatus.UNAUTHORIZED) @ExceptionHandler(value = {SginCheckException.class}) public Result sginCheckException(SginCheckException e) { return Result.fail(SystemErrorType.SIGNATURE_ERROR); } }
5.最后就是在需要鉴权的接口上贴上注解
// 调用方法语法 @beanname.methodname() @ApiOperation(value = "会员注册", notes = "会员注册", httpMethod = "POST") @PostMapping("/register") @PreAuthorize("@sc.checkSgin()") public Result register(@RequestBody @Valid MemberRegisterParam memberRegisterParam, HttpServletRequest request) { log.error("会员注册:" + memberRegisterParam); return memberService.register(memberRegisterParam, request); }
总结
当然这个注解还有很多用法,我只是记录一下我的使用方法。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。