原创

利用@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);
 }

结束语:

当然这个注解还有很多用法.我只是记录一下我的使用方法.不喜勿喷.
正文到此结束
Loading...