0

私は現在Grailsのソリューションに取り組んでおり、次のセキュリティプラグインをインストールしました。

  • Spring Security Core
  • SpringセキュリティUI

基本的に、次のセキュリティ構造のソリューションがあります。

  • スーパーユーザー
  • 管理者(さまざまな事業分野向け)
  • ユーザー(さまざまな事業領域内)

したがって、基本的には、さまざまなビジネスエリア管理者が自分のエリアを管理できるようにするためにSpring Security UIをインストールしました。彼らは、自分のエリアのユーザーのみを検索し、自分のユーザーを作成できるようにするためにUIを使用できる必要があります。エリアを作成し、自分のエリアでのみユーザーを編集します。ただし、SpringセキュリティUIを使用すると、アクセスブランケットアクセスを持つユーザーは何でもできます。

春のセキュリティドメインモデルに「エリア」というフィールドを追加したので、管理者がユーザーを検索しているときは、同じエリアのユーザーしか表示されないので、ユーザーを作成すると、自分だけが実行できるようになると考えていました。したがって、自分のエリアでは、自分のエリアのユーザーのみを編集できます。

以下は、Spring Security UIがユーザーを検索するために使用するコードですが、現在ログインしている管理者と同じエリアにいるユーザーのみを返すようにこれを変更できますか?またはもっと良い方法はありますか?

def userSearch = {

    boolean useOffset = params.containsKey('offset')
    setIfMissing 'max', 10, 100
    setIfMissing 'offset', 0

    def hql = new StringBuilder('FROM ').append(lookupUserClassName()).append(' u WHERE 1=1 ')
    def queryParams = [:]

    def userLookup = SpringSecurityUtils.securityConfig.userLookup
    String usernameFieldName = userLookup.usernamePropertyName

    for (name in [username: usernameFieldName]) {
        if (params[name.key]) {
            hql.append " AND LOWER(u.${name.value}) LIKE :${name.key}"
            queryParams[name.key] = params[name.key].toLowerCase() + '%'
        }
    }

    String enabledPropertyName = userLookup.enabledPropertyName
    String accountExpiredPropertyName = userLookup.accountExpiredPropertyName
    String accountLockedPropertyName = userLookup.accountLockedPropertyName
    String passwordExpiredPropertyName = userLookup.passwordExpiredPropertyName

    for (name in [enabled: enabledPropertyName,
                  accountExpired: accountExpiredPropertyName,
                  accountLocked: accountLockedPropertyName,
                  passwordExpired: passwordExpiredPropertyName]) {
        Integer value = params.int(name.key)
        if (value) {
            hql.append " AND u.${name.value}=:${name.key}"
            queryParams[name.key] = value == 1
        }
    }

    int totalCount = lookupUserClass().executeQuery("SELECT COUNT(DISTINCT u) $hql", queryParams)[0]

    Integer max = params.int('max')
    Integer offset = params.int('offset')

    String orderBy = ''
    if (params.sort) {
        orderBy = " ORDER BY u.$params.sort ${params.order ?: 'ASC'}"
    }

    def results = lookupUserClass().executeQuery(
            "SELECT DISTINCT u $hql $orderBy",
            queryParams, [max: max, offset: offset])
    def model = [results: results, totalCount: totalCount, searched: true]

    // add query params to model for paging
    for (name in ['username', 'enabled', 'accountExpired', 'accountLocked',
                  'passwordExpired', 'sort', 'order']) {
        model[name] = params[name]
    }

    render view: 'search', model: model
}

編集....

私はそれが以下のコードと関係があるかもしれないと信じています:

def results = lookupUserClass().executeQuery(
            "SELECT DISTINCT u $hql $orderBy",
            queryParams, [max: max, offset: offset])

現在ログインしているユーザー「Area」がユーザーと同じエリアに等しいユーザーのリストを検索するように、このステートメントを変更する必要があると思います。誰かがこれを手伝ってくれませんか?

編集2....。

これを調べてユーザーエリアを取得できました。データベースへのクエリを変更して、管理者が検索しているのと同じエリアを持つユーザーを探すだけです。私は運が悪かったので次のことを試みました、これは単純でなければならないことを知っているので誰かがこれを手伝ってくれますか?

        def user = springSecurityService.currentUser
        def userArea = user.area

        def hql = new StringBuilder('FROM ').append(lookupUserClassName()).append(' u WHERE 1=1 AND u.area = userArea')

編集3......。

おかげで私の問題の半分は解決されました笑、今はAjaxのピースだけです:

ユーザーの面積が現在ログインしているユーザーと同じである結果のみを返すようにAjax関数の検索を変更するために、以下のコードを試しました。

String username = params.term
            String usernameFieldName = SpringSecurityUtils.securityConfig.userLookup.usernamePropertyName
            def user = springSecurityService.currentUser

            setIfMissing 'max', 10, 100

            def results = lookupUserClass().executeQuery(
                    "SELECT DISTINCT u.$usernameFieldName " +
                    "FROM ${lookupUserClassName()} u " +
                    "WHERE LOWER(u.$usernameFieldName) LIKE :name AND LOWER(u.area) = :area " +
                    "ORDER BY u.$usernameFieldName",
                    [name: "${username.toLowerCase()}%"],
                    [area: "user.area"],
                    [max: params.max])

また、以下のようにパラメータを変更してみました。

[area: user.area]
4

1 に答える 1

1

コントローラーは HQL クエリを構築しているため、単に " " と言うのではなく、名前付きパラメーターを使用して値をマップWHERE u.area = userAreaに入れる必要があります。queryParams

    def user = springSecurityService.currentUser

    def hql = new StringBuilder('FROM ').append(lookupUserClassName()).append(
        ' u WHERE u.area = :userArea ')
    def queryParams = [userArea:user.area]

問題の 2 番目の部分 (Ajax ビット) については、LOWER変換が必要だとは思えません。また、すべてのクエリ パラメーターを 1 つのマップに入れる必要があります (2 番目のマップ パラメーターは、ページネーション設定のためだけです)。

def results = lookupUserClass().executeQuery(
   "SELECT DISTINCT u.$usernameFieldName " +
   "FROM ${lookupUserClassName()} u " +
   "WHERE LOWER(u.$usernameFieldName) LIKE :name AND u.area = :area " +
   "ORDER BY u.$usernameFieldName",
   [name: "${username.toLowerCase()}%", area:user.area],
   [max: params.max])

areaチェックで大文字と小文字を区別しないようにしたい場合は、そのままにしておきLOWER(u.area) = :areaますが、テスト対象の値を小文字に変換する必要もあります。

   [name: "${username.toLowerCase()}%", area:user.area.toLowerCase()],
于 2012-09-28T11:27:00.820 に答える