2012-06-04 3 views
1

В моем приложении у меня есть объект верхнего уровня, называемый Organization. Отношения между пользователем и организацией - это многие ко многим.Роли пользователей безопасности безопасности в организации

Из-за этого я мог бы иметь следующий сценарий:

  • UserA имеет роль ROLE_ADMIN для OrganizationA
  • UserA имеет роль ROLE_USER для OrganizationB

Мне нужно, чтобы гарантировать, что когда UserA доступ к ресурсам для OrganizationB он не делает это как ADMIN. Поэтому мне нужна дополнительная проверка того, что пользователь имеет правильные роли на уровне организации. Есть ли что-то встроенное в Spring Security, которое позволяет это? Если нет, то кто-нибудь знает, как лучше всего это решить?

UPDATE: Немного больше информации ...

пользователь входит в систему и выбирает, какие орг они хотят работать. Это сохраняется в сеансе. Кроме того, URL-адреса заблокированы с помощью аннотации Secured. Это означает, что если UserA должен был войти в систему и выбрать OrgA, они должны иметь доступ к/admin/user/create, однако, если они войдут в систему и выберите OrgB, у них не будет доступа к этому URL.

Долгий путь - добавить дополнительные проверки в каждый метод, когда это имеет значение. Поэтому вызовите некоторый метод обслуживания, в котором говорится: «Хорошо, вы администратор для OrgA, но не для OrgB, и вы вошли в систему с помощью OrgB, поэтому отклоните этот запрос».

Я надеюсь на более эффективный способ обработки грааля/пружины.

+0

Возможно, вам понадобится дополнительная информация, иначе сложно предложить конкретный подход. Какие различия между ресурсами для разных организаций, например? –

+0

Как администратор или организация, я могу создавать пользователей. Я не хочу разрешать это для UserA в OrganizationB. Такого рода вещи. – Gregg

+0

Хорошо, я должен был сказать: «Как ваше приложение различает разные ресурсы?» Что такое «ресурс» в этом контексте? Например, используете ли вы разные URL-адреса для разных организаций? –

ответ

2

Возможно, вы можете сделать это с помощью пользовательского AccessDecisionVoter. Метод vote предоставит вам «атрибуты конфигурации» для ресурса (метод или URL-адрес), который обычно будет требуемыми ролями, и вы можете получить роли/полномочия текущего пользователя либо непосредственно из объекта Authentication, либо путем чтения текущей организации и выбора соответствующих ролей для пользователя.

Я предполагаю, что у вас есть способ дифференцировать роли пользователя на основе выбранной ими организации.

По существу, вы должны написать расширенную версию стандарта RoleVoter, которая учитывает организацию.

+0

А, ок. Это имеет смысл. Я отдам сообщение и отчитаюсь. Спасибо за информацию. – Gregg

0

Я думаю, что я немного поздно здесь, но это то, что работает для меня:

При выборе организации, вы можете установить новый объект Authentication с новыми ролями в сеансе (предыдущий объект аутентификации получает недействительным). Что-то вроде этого:

@RequestMapping(value = "/org-a") 
String orgA(HttpServletRequest request) { 
    request.getSession().setAttribute("org", "org-a") 
    Organization org = new Organization("org-a") 
    reloadRolesForAuthenticatedUser(org) 
    .... 
} 

private void reloadRolesForAuthenticatedUser(Organization org) { 
    Authentication auth = SecurityContextHolder.getContext().getAuthentication() 
    List<String> newRoles = getRoles(auth.getPrincipal().getUsername(), org) 
    List<GrantedAuthority> authorities = getAuthorities(newRoles) 
    Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(),auth.getCredentials(),authorities) 
    SecurityContextHolder.getContext().setAuthentication(newAuth) 
} 


private List<GrantedAuthority> getAuthorities(List<String> roles) { 
    List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>() 
    if (!roles.isEmpty()) { 
     for (String r : roles) { 
      auths.add(new SimpleGrantedAuthority(r)) 
     } 
    } 
    return auths 
}