私たちのシステムでは、ユーザーが複数の組織のメンバーになり、組織ごとに異なる役割を持つことができるようにする必要があります。私の UserRole クラスは次のように変更されました。
class UserRole implements Serializable {
User user
Role role
Organization organization
}
これを機能させるには、次のようなカスタム Voter を作成する必要がありました。
class OrganizationRoleVoter extends RoleVoter {
@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
int result = ACCESS_ABSTAIN
Collection<? extends GrantedAuthority> authorities = extractAuthorities(authentication)
GrailsWebRequest request = RequestContextHolder.currentRequestAttributes()
Organization selectedOrganization = (Organization) request.session.getAttribute("selectedOrganizationSession")
attributes.each {ConfigAttribute attribute ->
if (this.supports(attribute)) {
result = ACCESS_DENIED
for (GrantedAuthority authority : authorities) {
if (attribute.attribute.equals(authority.authority)) {
def user = User.findByUsername(authentication.name)
def role = Role.findByAuthority(authority.authority)
if (UserRole.findByUserAndOrganizationAndRole(user, selectedOrganization, role)) {
result = ACCESS_GRANTED
break
}
}
}
}
}
return result
}
Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {
return authentication.getAuthorities();
}
}
私たちが抱えている問題は、Remember Me Cookie にあります。それを使用する場合、一部のリクエスト (すべてではない) で、アプリは完全な認証を強制します。私はこれが ajax リクエストで発生するのを見たことがありますが、私たちのアプリは 90% ajax であるため、決定的にそうであるとは言えません。ただし、すべてのユーザーレベルコントローラーに次のように注釈を付けています。
@Secured(['ROLE_USER', 'IS_AUTHENTICATED_REMEMBERED'])
(すべての使用には ROLE_USER ロールが必要であり、必要に応じて他のロールを持つことができます)。
これは設定です:
grails.plugins.springsecurity.voterNames = [
'organizationRoleVoter', 'authenticatedVoter'
]
grails.plugins.springsecurity.logout.handlerNames =
['rememberMeServices',
'securityContextLogoutHandler',
'securityEventListener']
そのため、この時点では、remember me cookie 認証を許可するようにアプリケーションに指示しているのに、アプリケーションが完全な認証を必要とする理由がわかりません。ドキュメントを読み間違えていますか?それとも、投票者を間違って実装しましたか?