Прежде всего вам нужно написать BeanAccessor
, как показано ниже:
@Component
public class BeanAccessor implements ApplicationContextAware {
private static ApplicationContext context;
public static ObjectMapper getObjectMapper() {
return getBean(ObjectMapper.class);
}
public static <T> T getBean(Class<T> beanClass, Object... args) {
return context.getBean(beanClass, args);
}
private static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
}
, затем нам нужно написать новый класс для обеспечения безопасности метода, например:
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {
private Object filterObject;
private Object returnObject;
private Object target;
public CustomMethodSecurityExpressionRoot(Authentication authentication) {
super(authentication);
}
CustomMethodSecurityExpressionRoot setTarget(Object target) {
this.target = target;
return this;
}
@Override
public void setFilterObject(Object filterObject) {
this.filterObject = filterObject;
}
@Override
public Object getFilterObject() {
return filterObject;
}
@Override
public void setReturnObject(Object returnObject) {
this.returnObject = returnObject;
}
@Override
public Object getReturnObject() {
return returnObject;
}
@Override
public Object getThis() {
return target;
}
}
наконец, нам нужны пользовательскиеобработчик выражения безопасности метода:
@Component
public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
@Autowired
private CustomPermissionEvaluator customPermissionEvaluator;
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
@Override
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
final CustomMethodSecurityExpressionRoot root = BeanAccessor.getBean(CustomMethodSecurityExpressionRoot.class, authentication);
root.setPermissionEvaluator(customPermissionEvaluator);
root.setTrustResolver(this.trustResolver);
root.setRoleHierarchy(getRoleHierarchy());
root.setTarget(invocation.getThis());
return root;
}
}
теперь в вашем контроллере метод yo может определять @PreAuthorize("isProfileOwner(#id)")
аннотации, которые ваш метод отображения страницы профиля пользователя выглядит следующим образом:
@PreAuthorize("isProfileOwner(#id)")
@GetMapping("{id}")
public String show(@PathVariable("id") Long id, Model model) {
//omitted
}
все в порядке, но нам нужнонапишите isProfileOwner()
метод в наш CustomMethodSecurityExpressionRoot
класс, например:
public boolean isProfileOwner(Long id) {
//add logic here and you are ready
}
, также вы можете проверить это post