web-dev-qa-db-ja.com

ロールとパーミッションを備えたSpring Security

権限を使用してロールベースのセキュリティを設定しようとしています。私はSpring-Securityと一緒にこれをやろうとしています。

ACLを設定したくないのは、私の要件にとってはやり過ぎだからです。

この 記事 で説明されているように、単純なアクセス許可とロールが必要です。残念ながら、この記事では特定のソリューションの実装方法については説明していません。

誰かがすでにこれを試みて、私を正しい方向に向けることができますか?実装について説明する別のブログエントリがあるかもしれません。

どうもありがとうございました。

76
flash

それを実装するには、次のようにする必要があるようです。

  1. モデル(ユーザー、ロール、アクセス許可)と、特定のユーザーのアクセス許可を取得する方法を作成します。
  2. 独自のorg.springframework.security.authentication.ProviderManagerを定義し、カスタムorg.springframework.security.authentication.AuthenticationProviderに構成(プロバイダーを設定)します。この最後のメソッドは、認証メソッドにAuthenticationを返す必要があります。Authenticationは、org.springframework.security.core.GrantedAuthorityで設定する必要があります。この場合は、特定のユーザーのすべてのアクセス許可です。

この記事の秘trickは、ユーザーにロールを割り当てることですが、Authentication.authoritiesオブジェクトでそれらのロールのアクセス許可を設定することです。

そのためには、APIを読んで、すべてを実装する代わりに基本的なProviderManagerとAuthenticationProviderを拡張できるかどうかを確認することをお勧めします。 org.springframework.security.ldap.authentication.LdapAuthenticationProviderでカスタムLdapAuthoritiesPopulatorを設定して、ユーザーの正しいロールを取得します。

今回はあなたが探しているものを手に入れたと思います。幸運を。

30
ezequielb

私は問題の記事の著者です。

間違いなく複数の方法がありますが、私が通常行う方法は、役割と権限を知っているカスタムUserDetailsを実装することです。 RolePermissionは、作成するカスタムクラスにすぎません。 (空想なものはありません-Roleには名前とPermissionインスタンスのセットがあり、Permissionには名前があります。)getAuthorities()GrantedAuthorityオブジェクトを返しますこのように見える:

PERM_CREATE_POSTPERM_UPDATE_POSTPERM_READ_POST

のようなものを返す代わりに

ROLE_USERROLE_MODERATOR

UserDetails実装にgetRoles()メソッドがある場合、ロールは引き続き使用可能です。 (持っていることをお勧めします。)

理想的には、ユーザーに役割を割り当て、関連する許可が自動的に入力されます。これには、そのマッピングを実行する方法を知っているカスタムUserDetailsServiceが含まれ、データベースからマッピングを取得するだけです。 (スキーマの記事を参照してください。)

次に、ロールではなく許可の観点から許可ルールを定義できます。

お役に立てば幸いです。

76
Willie Wheeler

基本的な手順は次のとおりです。

  1. カスタム認証プロバイダーを使用する

    <bean id="myAuthenticationProvider" class="myProviderImplementation" scope="singleton">
    ...
    </bean>
    
  2. カスタムプロバイダーがカスタムUserDetails実装を返すようにします。このUserDetailsImplには、次のようなgetAuthorities()があります。

    public Collection<GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> permissions = new ArrayList<GrantedAuthority>();
        for (GrantedAuthority role: roles) {
            permissions.addAll(getPermissionsIncludedInRole(role));
        }
        return permissions;
    }
    

もちろんここから、特定の要件に合わせて多くの最適化/カスタマイズを適用できます。

6
gpeche

これが最も簡単な方法です。グループ権限とユーザー権限を許可します。

-- Postgres syntax

create table users (
  user_id serial primary key,
  enabled boolean not null default true,
  password text not null,
  username citext not null unique
);

create index on users (username);

create table groups (
  group_id serial primary key,
  name citext not null unique
);

create table authorities (
  authority_id serial primary key,
  authority citext not null unique
);

create table user_authorities (
  user_id int references users,
  authority_id int references authorities,
  primary key (user_id, authority_id)
);

create table group_users (
  group_id int references groups,
  user_id int referenecs users,
  primary key (group_id, user_id)
);

create table group_authorities (
  group_id int references groups,
  authority_id int references authorities,
  primary key (group_id, authority_id)
);

次に、META-INF/applicationContext-security.xmlで

<beans:bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="passwordEncoder" />

<authentication-manager>
    <authentication-provider>

        <jdbc-user-service
                data-source-ref="dataSource"

                users-by-username-query="select username, password, enabled from users where username=?"

                authorities-by-username-query="select users.username, authorities.authority from users join user_authorities using(user_id) join authorities using(authority_id) where users.username=?"

                group-authorities-by-username-query="select groups.id, groups.name, authorities.authority from users join group_users using(user_id) join groups using(group_id) join group_authorities using(group_id) join authorities using(authority_id) where users.username=?"

                />

          <password-encoder ref="passwordEncoder" />

    </authentication-provider>
</authentication-manager>
5
Neil McGuigan

完全を期すために(他の誰かがゼロから実装する必要はないかもしれません):

他の皆と同様に、私たちは独自の小さなライブラリを実装しました。開発者が毎回それを再実装する必要がないように、物事を簡単にするはずです。このアプローチはデフォルトの許可ベースのアプローチよりもはるかに優れているため、春のセキュリティがそのままrbacのサポートを提供するのは素晴らしいことです。

Github (OSS、MIT license)を見て、ニーズに合っているかどうかを確認してください。基本的には、ロール<->特権マッピングのみに対応しています。不足している部分は、基本的にユーザー<->ロールマッピングです。グループ(racf/adグループ)をロール(1:1)にマッピングするか、追加のマッピングを実装します。これはプロジェクトごとに異なるため、実装を提供することは意味がありません。

基本的にこれを内部的に使用しているため、最初からrbacを使用できます。アプリケーションが成長している場合は、後で他の実装に置き換えることができますが、セットアップを最初から正しく行うことが重要です。

Rbacを使用しない場合、コードベース全体にアクセス許可が散在している可能性が高く、後で(ロールに)それらを抽出/グループ化するのは困難です。生成されたグラフは、後でそれについて推論/再構築するのにも役立ちます。

1
Alexander Pilch