web-dev-qa-db-ja.com

複数のロールをチェックするために<sec:authorize access = "hasRole( 'ROLES)">を使用する方法は?

Spring Security JSP taglibを使用して、ロールに基づいて条件付きでコンテンツを表示したい。しかし、Spring Security 3.1.xでは1つのロールのみをチェックしています。

使用できますが、ifAllGrantedは非推奨です。

何か助け?

43

春のセキュリティには特別なセキュリティ表現があります。

hasAnyRole(ロールのリスト)-指定されたロールのいずれかがユーザーに許可されている場合はtrue(文字列のコンマ区切りリストとして指定)。

私はそれを使ったことがありませんが、まさにあなたが探しているものだと思います。

使用例:

<security:authorize access="hasAnyRole('ADMIN', 'DEVELOPER')">
    ...
</security:authorize>

ここに リファレンスドキュメントへのリンク があり、標準のスプリングセキュリティ式が説明されています。また、ここに discussion があります。必要に応じてカスタム式を作成する方法を説明しました。

76
dimas

@dimasの答えは、あなたの質問と論理的に一致していません。 ifAllGrantedは、hasAnyRoleに直接置き換えることはできません。

Spring Security 3—> 4移行ガイド から:

古い:

_<sec:authorize ifAllGranted="ROLE_ADMIN,ROLE_USER">
    <p>Must have ROLE_ADMIN and ROLE_USER</p>
</sec:authorize>
_

新規(SPeL):

_<sec:authorize access="hasRole('ROLE_ADMIN') and hasRole('ROLE_USER')">
    <p>Must have ROLE_ADMIN and ROLE_USER</p>
</sec:authorize>
_

ifAllGrantedhasAnyRoleに直接置き換えると、springはORの代わりにANDを使用してステートメントを評価します。つまり、hasAnyRoleは、認証されたプリンシパルに指定されたロールの少なくとも1つがである場合、trueを返しますが、Springの(現在、セキュリティ4)ifAllGrantedメソッドは、認証されたプリンシパルに指定されたロールのallが含まれる場合にのみtrueを返しました。

TL; DR:Spring Security Taglibの新しい認証式言語であるhasRole('ROLE_1') and hasRole('ROLE_2')を使用してifAllGrantedの動作を複製するパターンを使用する必要があります。

5
acidnbass

私はhasAnyRole('ROLE_ADMIN','ROLE_USER')を使用しましたが、エラーの下でBean作成を取得していました

_Error creating bean with name     'org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0': Cannot create inner bean '(inner bean)' of type [org.springframework.security.web.access.expression.ExpressionBasedFilterInvocationSecurityMetadataSource] while setting bean property 'securityMetadataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#2': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.security.web.access.expression.ExpressionBasedFilterInvocationSecurityMetadataSource]: Constructor threw exception; nested exception is Java.lang.IllegalArgumentException: Expected a single expression attribute for [/user/*]
_

それから私は試した

access="hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')"そして、私にとってはうまく機能しています。

私のユーザーの1人はユーザーであると同時に管理者です。

このためには、_use-expressions="true" auto-config="true"_の後にhttpタグを追加する必要があります

_<http use-expressions="true" auto-config="true" >.....</http>
_
1
Musaddique