2012-06-28 34 views
4

用戶變化,我想立即傳播在我的Grails應用程序的用戶改變(用戶角色的變化)(我使用Spring Security的插件)。鐳驗證在Grails應用程序

我發現這一點:

springSecurityService.reauthenticate(userName) 

,但這個工程的當前登錄的用戶,而不是改變一個!

是否有任何簡單的解決方案(即使強制註銷更改的用戶將足以滿足我)。

用於此的用例是當管理員更改某個其他用戶角色時。如果更改的用戶已登錄,則在Spring Security的上下文中不會立即看到角色更改。

回答

4

由於法比亞諾,我想出了以下解決方案,它的工作原理:

resources.groovy

import org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy 
import org.springframework.security.web.session.ConcurrentSessionFilter 
import org.springframework.security.core.session.SessionRegistryImpl 
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy 

// Place your Spring DSL code here 
beans = { 
    // bind session registry 
    sessionRegistry(SessionRegistryImpl) 

    sessionAuthenticationStrategy(ConcurrentSessionControlStrategy, sessionRegistry) { 
     maximumSessions = -1 
    } 

    concurrentSessionFilter(ConcurrentSessionFilter){ 
     sessionRegistry = sessionRegistry 
     expiredUrl = '/login/concurrentSession' 
    } 
} 

MyService.groovy

def sessionRegistry 

def expireSession(User user) { 
     def userSessions = sessionRegistry.getAllSessions(user, false) 
     // expire all registered sessions 
     userSessions.each { 
      log.debug "Expire session [$it] of the user [$user]" 
      it.expireNow() 
     } 
} 

很容易:-)

更新:

另外不要忘記註冊HttpSessionEventPublisher,並按照Filter Documentations使用不同的方式將concurrentSessionFilter添加到Config.groovy中。

的web.xml

<listener> 
    <listener-class> 
     org.springframework.security.web.session.HttpSessionEventPublisher 
    </listener-class> 
</listener> 
1

花了很長的時間同樣的問題瀏覽互聯網。建議的解決方案不起作用(可能我沒那麼幸運:)。因此,這裏是我的方式

首先,我們創建一個Grails服務是這樣的:

class SecurityHelperService { 
    final Set<String> userUpdates = new HashSet<String>() 

    public void markUserUpdate(String username) { 
     synchronized (userUpdates) { 
      userUpdates.add(username) 
     } 
    } 

    public boolean clearUserUpdate(String username) { 
     synchronized (userUpdates) { 
      return userUpdates.remove(username) != null 
     } 
    } 

    public boolean checkUserUpdate() { 
     def principal = springSecurityService.principal 

     if (principal instanceof org.springframework.security.core.userdetails.User) { 
      synchronized (userUpdates) { 
       if (!userUpdates.remove(principal.username)) { 
        return true 
       } 
      } 

      springSecurityService.reauthenticate(principal.username) 

      return false 
     } 

     return true 
    } 
} 

在我們創建了一個Grails的過濾器來檢查當前用戶權限已被改變了grails-app/conf目錄,例如

class MyFilters { 
    SecurityHelperService securityHelper 

    def filters = { 
     userUpdateCheck(controller: '*', action: '*') { 
      before = { 
       if (!securityHelper.checkUserUpdate()) { 
        redirect url: '/' 

        return false 
       } 

       return true 
      } 
     } 
    } 
} 

這一切。當代碼更新用戶權限,我們稱之爲服務方法

securityHelper.markUserUpdate('username') 

當在線用戶下一次訪問頁面時,他/她的權限自動檢查並重新加載每次。無需手動註銷。

可選,我們在一個新的登錄清除以前的用戶更新,以避免不必要的重定向在過濾器

希望這有助於