2011-06-20 8 views
7

Mam prostą aplikację Grails z zainstalowaną wtyczką Spring Security Core i działa poprawnie. Jednak nie znalazłem żadnego rozwiązania problemu z aktualizacją zalogowanych uprawnień użytkownika w kontekście zabezpieczeń. Nie mówię o aktualizowaniu danych bieżącego użytkownika (np. SpringSecurityService.reauthenticate).Wtyczka Grails Spring Security - modyfikacja zalogowanych uprawnień użytkownika

Mój problem: Używam prostej aplikacji do zarządzania użytkownikami, w której używane są uprawnienia ROLE_ADMIN i ROLE_USER. Teraz mam dwóch administratorów zalogowanych w tym samym czasie (z uprawnieniem ROLE_ADMIN) z różnych komputerów, a jeden administrator postanawia zmienić uprawnienia drugiego administratora z ROLE_ADMIN na ROLE_USER.

Jak mogę zaktualizować użytkownika i rolę, aby zmodyfikowany użytkownik (z nową rolą ROLE_USER) nie mógł wykonać żadnych działań poziomowych ROLE_ADMIN i został natychmiast przekierowany na strony poziomu ROLE_USER? Czy istnieje sposób aktualizacji kontekstu zabezpieczeń, więc nie muszę wykonywać dodatkowych sprawdzeń we wszystkich działaniach kontrolera, czy uprawnienia zalogowanego użytkownika zostały zmienione? Czy mogę w jakiś sposób użyć własności cahceUsers? Nie zmodyfikowałem cacheUsers i domyślnie domyślnie jest to wartość false. Proszę popraw mnie jeżeli się mylę.

EDIT: sekwencji, która jest przyczyną problemu jest

  1. Administrator "A" modyfikuje administratorem "B" i wyznacza nową rolę (ROLE_USER) dla administratora "B"

  2. kod dzwoni pod numer PersonRole.removeAll(personInstanceB) and PersonRole.create(personInstanceB, roleAdmin) i wszystko jest normalnie aktualizowane:

  3. w tym samym czasie Administrator "B" jest już zalogowany, gdy jego władze zostały zmodyfikowane. Administrator "B" może kontynuować pracę na ograniczonych stronach ROLE_ADMIN, dopóki się nie wyloguje i nie zaloguje się ponownie. Dopiero wtedy władze są aktualizowane i Administrator "B" ma nową rolę (ROLE_USER)

  4. Chcę, aby Administrator "B" był przekierowywany na strony ROLE_USER, gdy użytkownik jest aktualizowany o nową rolę, a nie tylko po wylogowaniu/login

  5. dzwonienie pod numer springSecurityService.reauthenticate personInstanceB.username) powoduje, że administrator "A" jest "zalogowany" jako Administrator "B", więc to nie działa.

Wszelkie pomysły byłyby bardzo mile widziane. Być może przegapiłem coś prostego tutaj, ale nie mam pojęcia, jakie byłoby rozwiązanie.

Cheers, mizzzto

Odpowiedz

11

To niesprawdzone ale dać mu spróbować

w klasie kontroler/usług,

... 

User user = User.get(springSecurityService.principal.id) //get the user 
Role adminRole = //get or create the admin Role 
UserRole.remove user, role // remove admin Role 

Role userRole = // get or create the user Role 
UserRole.create user, role //add the user Role 

... 

if (!user.hasErrors() && user.save(flush: true)) { 
    springSecurityService.reauthenticate user.username // refresh the users security deatils 
} 

.... 

EDIT

To jest dużo jaśniejsze teraz.

Co mógłbym zrobić ze szczytu mojej głowy to użyć funkcji użytkownika przełącznika.zobacz Switch User

  • najpierw ustawić atrybut useSwitchUserFilter do true
  • Zaleca się zrobić nową rolę (np ROLE_SWITCH_USER) dla tego przywilej.
  • na stronie administratora gdzieś

    <sec:ifAllGranted roles='ROLE_SWITCH_USER'> 
        <form action='/j_spring_security_switch_user' method='POST'> 
         Switch to user: <input type='text' name='j_username'/> <br/> 
         <input type='submit' value='Switch'/> 
        </form> 
    </sec:ifAllGranted> 
    
  • zalogować się jako użytkownik chcesz edytować za pomocą nazwy użytkownika
  • zmienić swoje ustawienia ról poprzez wywołanie metody adminToUser() poniżej (na przykład)
  • przełącz się z powrotem na pierwotnego użytkownika
  • Gotowe.

- Można używać w postaci kodu pierwsza odpowiedź do stworzenia metody w kontrolerze lub usługi, które wymagają userInstance i zmienia thier rolę z administratorowi użytkownika.

def adminToUser(user, adminRole, userRole){ 
    UserRole.remove user, adminRole 
    UserRole.create user, userRole 
    if (!user.hasErrors() && user.save(flush: true)) { 
     springSecurityService.reauthenticate user.username 
    } 
} 
+0

cześć, dzięki za odpowiedzi. Zanim opublikowałem moje pytanie, już to zrobiłem, jak opisałeś. Oznacza to jednak, że jeśli jesteś administratorem i aktualizujesz uprawnienia innego administratora ->, to wywołanie springSecurityService.reauthenticate user.username spowoduje, że sesja zostanie zaktualizowana za pomocą poświadczeń zmodyfikowanego użytkownika. A to znaczy, że właśnie "zalogowałeś się" jako użytkownik, który zmodyfikowałeś. Nie chcę tego :) Będę edytować mój post, aby był bardziej przejrzysty na tym, co robię. – mizzzto

+0

@mizzzto zobacz EDIT! – gotomanners

+0

dziękuję bardzo, wydaje się działać dobrze teraz, tak proste, a jednocześnie bardzo potężne! :) Chociaż naprawdę powinien być jakiś łatwiejszy sposób powiadomienia zmodyfikowanego użytkownika, że ​​jego uprawnienia zostały zmienione podczas logowania użytkownika. Muszę dojść do sedna :) – mizzzto

6

Mam rozwiązać ten problem poprzez Ponowne uwierzytelnianie dwukrotnie:

zapisać nazwę administratora, który degradacji innego użytkownika:

def originalUserName = springSecurityService.principal.name 
springSecurityService.reauthenticate user.username 
springSecurityService.reauthenticate originalUserName 
Powiązane problemy