Проблем с използването на @PreAuthorize
Closed this issue · 9 comments
Привет! Опитвам се да използвам спринг секюрити, за да разреша на логнат потребител да трие и променя съдържанието, което е генерирал(например своя оферта). Видях, че в ведно от ишутата сте коментирали същата тема с един колега. Следвам стъпките, но в контролера не ми се резолва @PreAuthorize("isOwner(#id)") и явно пропускам нещо някъде.
Тук ми е имплементация на MethodSecurityExpressionOperations в която метода isOwner стои неактивен и не се използва
Следва SecurityExpressionHandler
Кофигурацията с новата анотация @EnableMethodSecurity
И в контролера "вълшебния" метод, както го наричаш стои неизползваем
Поздрави и успешен ден от мен! :)
Привет!
А има ли го някъде комитнато това, предпочитам кода пред снимка на кода ;-)
Поздрави,
Л.
Привет отново!
Да, извинявам се, пропуснах да сложа и линк - https://github.com/MilenaDimova/real-estate-project
Поздрави! :)
Ок, благодаря, после ще го видя!
Поздрави,
Л.
За съжаление, това нещо няма да работи в новия спринг, поради промените в DefaultMethodSecurityExpressionHandler
. Опитах да екстендвам AbstractSecurityExpressionHandler
но е доста тегаво и вече не съм сигурен че е удачно решение. :-) На този момент не мога да му отделя достатъчно време, така че ти предлагам едно малко по... дървенко но все пак нелошо решение. Може в @PreAuthorize
да викаш метод на бийн. Така:
@PreAuthorize("@offerService.isOwner(#principal.name, #uuid)")
@DeleteMapping("/offers/{id}")
public String deleteOffer(
Principal principal,
@PathVariable("id") UUID uuid) {
...
}
По натам ще му отделя малко повечко време. И без това трябва да мигрираме някакви сървиси на Спринг 3 и оттам съм черпил вдъхновение :))) Като имам повечко информация може да пиша тук. Остава изводът, че трябва да се внимава повечко при наследяване на спринговски класове, които не са абстрактни. Иначе боли в даден момент... :(
Поздрави,
Л.
Добре, връщам се на предния вариант, поне е работещ :) Предполагам сега в SecurityConfiguration класа трябва да сложа новата анотация - @EnableMethodSecurity вместо @EnableGlobalMethodSecurity(prePostEnabled = true)?
Благодаря за бързата реакция! Ще следя за инфо по въпроса тук.
Поздрави,
Милена Димова
Мисля, че си ок с EnableGlobalMethodSecurity
:
EnableGlobalMethodSecurity provides AOP security on methods. Some of the annotations that it provides are PreAuthorize, PostAuthorize.
Другото е за настройки с http security-то в конфига. Да видим и ние в работата какво ще правим тези дни с това "проблемче" :-)
Поздрави,
Л.
Не става с @EnableGlobalMethodSecurity защото е деприкейтед. Направих си няколко експеримента и без никаква допълнителна анотация в SecurityConfiguration класа, @PreAuthorize("@offerService.isOwner(#principal.name, #id)") спира да работи и трие всички оферти независимо от ролята на логнатия потребител. В случая с @EnableMethodSecurity, делийта работи, както се очаква, но спира да ми работи offerService-а в контролера и ми излиза, че offerService е null. Леко се обърках какво точно се случва... :)
Поздрави!
Хах! Това е най-абсурдната грешка, на която съм попадал в последните 3-4 години :-) Унищожи ми вечерта и лекцията с колегите утре, помощта за останалите колеги и личния живот, но мога да ти обясня какво става. :-))
Значи ползваме @EnableMethodSecurity
+ @Preauthorize
в контролера. Ок, @EnableGlobalMethodSecurity
са го деприкейтнали в новото секюрити бля бля бля бля, ноооо... остава голямата загадка, която си формулирала:
спира да ми работи offerService-а в контролера и ми излиза, че offerService е null
Абсолютен шах! Стъпка назад - как работи @PreAuthorize
? Тази анотация използва спринг AOP (чувала си за AOP, нали? :-) ) и като я сложиш на контролера той престава да бъде обикновен контролер, а вместо това става CGLIB прокси, както може би си забелязала от дебъгера. Само че по дифоулт CGLIB прокситата не пипат private методите. А ти погрешка си направила @PostMapping
-а прайвът:
@PostMapping("/add")
private String addConfirm(@Valid OfferAddBindingModel offerAddBindingModel, BindingResult bindingResult,
RedirectAttributes redirectAttributes, @AuthenticationPrincipal UserDetails userDetails) {
}
Скапаният спринг няма абсолютно никакъв проблем да работи с прайвът мапинги без предупреждение. Но когато се намеси и CGLIB AOP proxy... има "offerService е null" тъй като работи върху оригиналния обект, а не върху проксито. Ако го направиш public вече няма да е null ;-)
Яко, ъ? :-)
Поздрави,
Л.
Хах, малее, извинявам се за загубеното време, направо не мога да повярвам каква идиотска грешка съм допуснала :( Сега ще коригирам нещата в проекта. Още веднъж благодаря и дано не ми се сърдят много хора!
Поздрави и лека вечер!