9

Spring Security はロールベースの認可には優れていますが、ルールベースの認可に関しては不十分なようです。確かに、SpEL を介してそれを行う方法はありますが、複数の場所で同じロジックを使用できるように、そのロジックをサービスに引き出す方がはるかに優れている場合、そのルートに行くと、アノテーション内に承認ロジックがロックされるようです。

独自のSpEL式を追加する方法いくつかある ようですが、注目することは特に明確であり、私にとって意味のあるものでさえ不十分なようです。Groovy の柔軟性を考えると、依存関係を一緒にハードコーディングする必要はなく、セキュリティ ルール (または SpEL 拡張機能) を実行時に取得する何らかの方法が必要であると思います。

理想的ではありませんが、必要な新しいルールをすべて定義し、ミックスインとして挿入する (つまり、SecurityExpressionRoot.mixin MyRule1) という一見単純に見えるものでさえ、良い出発点になるでしょうが、うまくいかないようです。

これを行う例を知っている人はいますか?そうでない場合、どうすれば自分でこれを行うことができますか?


1 つの (簡略化された) 例: ユーザーは、4 つのフィールドのうち 3 つが特定のしきい値を超える値を持つ場合にのみ、オブジェクトに対して特定のアクション (つまり、サービス メソッドの実行) を実行できますが、オブジェクトが 3 日未満である場合にのみ実行できます。

class MyRule {

    boolean canTakeAction(Person person, MyThing myThing) {
        int numFieldsWithValues = 0
        if (myThing.field1 != null) { numFieldsWithValues++ }
        if (myThing.field2 != null) { numFieldsWithValues++ }
        if (myThing.field3 != null) { numFieldsWithValues++ }
        if (myThing.field4 != null) { numFieldsWithValues++ }

        return (numFieldsWithValues > 3) && (ageInDays(myThing) < 3)
    }

    int ageInDays(MyThing myThing) {
        ...
    }
}

そして、それはより単純なルールの 1 つです。

4

3 に答える 3

2

役割ベースの承認は最も簡単ですが、柔軟性に欠けます。これと対照的なのが、Spring セキュリティACL システムです。ACL を使用すると、実行時に誰がどのオブジェクトに対してを実行できるかを正確定義できます。反対に、これにははるかに複雑な設定が必要です。このための grails プラグインもあります。

SpEL 式でアノテーションを使用する方法は、これら両方の選択肢の間のどこかにあります。単純なロールよりも柔軟で、ACL よりも簡単です。Grails のメソッド セキュリティの概要を探している場合は、私が以前に書いたこのブログ記事が役立つかもしれません。

于 2012-12-18T22:45:26.503 に答える
1

動的構成機能を提供するRequestmapでルールを管理できます。

たとえば、最初に config.groovy でセキュリティ タイプを requestmap として定義します。

grails.plugins.springsecurity.securityConfigType = "Requestmap"

次に、次のように、User と Role に似た Requestmap ドメイン クラスを作成できます。

package com.app.auth
class Requestmap {

    String url
    String configAttribute

    static mapping = {
        cache true
    }

    static constraints = {
        url blank: false
        configAttribute blank: false
    }
}

User、Role、および Reqestmap はすべてデータベースに永続化されるため、サービスを再デプロイまたは再起動することなく、一部のコントローラーで CRUD アクションによってルールを簡単に変更できます。このような:

class RequestmapController {

def springSecurityService

...

def save = { 
    def requestmapInstance = new Requestmap(params) 
    if (!requestmapInstance.save(flush: true)) { 
        render view: 'create', model: [requestmapInstance: requestmapInstance] 
        return 
    }

    springSecurityService.clearCachedRequestmaps()     //This is important: to refresh the requestmap. Without it the rules remain unchanged.
    flash.message = "${message(code: 'default.created.message', args: [message(code: 'requestmap.label', default: 'Requestmap'), requestmapInstance.id])}" 
    redirect action: show, id: requestmapInstance.id 
    } 
}

ビューレイヤーでは、次のようなSpringセキュリティタグを使用して、認証が必要なメニュー、ボタン、およびその他の要素を管理できます。

<sec:access url="foo/bar">
    <li><g:link class="list" controller="foo" action="bar">Bar action</g:link></li>
</sec:access>

したがって、ビューも認可規則に準拠しています。

さらに、リクエスト マッピングの煩雑さを軽減するために利用できる階層ロール機能があります。

于 2012-12-19T04:15:54.187 に答える
0

投稿した例から、GContractsが探しているものかもしれません。GContract クロージャを実行するときにプリンシパルにアクセスする方法を理解する必要がありますが、それは契約メソッドにパラメーターとして渡すのと同じくらい簡単かもしれません。

于 2012-12-19T14:42:41.190 に答える