Я хочу реализовать метод авторизации с помощью Spring Boot AOP. Исходная идея заключается в том, что если возвращаемый объект, возвращаемый из вызовов REST, не прошел проверку авторизации, он выдаст несанкционированное исключение.
Я делаю это так:
@Aspect
@Component
public class AuthAspect {
@Around("AllRestExecPoint()")
public Object auth(ProceedingJoinPoint point) throws Throwable {
Object returnObject = point.proceed();
if (!checkAuthorization(returnObject)) {
throw new UnauthException();
}
return returnObject;
}
}
Однако проблема в том, что, если эта служба REST выполнит некоторую INSERT или UPDATE для моей БД, она выполнится перед проверкой моей авторизации. Таким образом, UnauthException
будет выброшено, но транзакция все еще фиксируется.
Первая попытка вручную создать транзакцию перед вызовом proceed()
и зафиксировать ее до возврата, но она не удалась.
@Aspect
@Component
public class AuthAspect {
private final EntityManager em;
@Autowired
public AuthAspect(EntityManager em) {
this.em = em;
}
@Around("AllRestExecPoint()")
public Object auth(ProceedingJoinPoint point) throws Throwable {
em.getTransaction().begin();
Object returnObject = point.proceed();
if (!checkAuthorization(returnObject)) {
throw new UnauthException();
}
em.getTransaction().commit();
return returnObject;
}
}
Это вызовет java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
.
Я искал в Интернете, и некоторые ответы должны изменить файл web.xml
, но я не хочу использовать xml для настройки.