私は現在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]