Я работаю с веб-сайтом Spring MVC и добавляю аутентификацию с помощью Active Directory через LDAP. Компания не хочет использовать полномочия AD для сопоставления разрешений для веб-сайта, у нас есть база данных, в которой перечислены разрешения каждого пользователя, поэтому я пытаюсь подключиться к ней, получить разрешения и добавить их в токен аутентификации пользователя.
Когда я только начинал, я сопоставлял полномочия группы пользователей AD с GrantedAuthoritiesMapper
, и у меня это работало. Это выглядело так:
public class ActiveDirectoryGrantedAuthoritiesMapper implements GrantedAuthoritiesMapper {
private static final String ROLE_ADMIN = "adminUserGroup";
public ActiveDirectoryGrantedAuthoritiesMapper()
{ }
public Collection<? extends GrantedAuthority> mapAuthorities(
final Collection<? extends GrantedAuthority> authorities)
{
Set<CustomAuthority> roles = EnumSet.noneOf(CustomAuthority.class);
for (GrantedAuthority authority : authorities)
{
if (ROLE_ADMIN.equals(authority.getAuthority()))
{
roles.add(CustomAuthority.ROLE_ADMIN);
}
//Default role for all users.
roles.add(CustomAuthority.ROLE_EMPLOYEE);
}
return roles;
}
}
Теперь я пытаюсь преобразовать его для запроса разрешений в нашей базе данных. Я отказался от GrantedAuthoritiesMapper
, чтобы сделать это по двум причинам. Во-первых, я не использую авторитеты из LDAP, так зачем их перехватывать? А также потому, что я не мог понять, как получить имя пользователя, вошедшего в систему внутри файла GrantedAuthoritiesMapper
. Я пытался использовать SecurityContext
, но он выдавал мне NullPointerException
всякий раз, когда я пытался вызвать context.getAuthentication().getName()
, я полагаю, потому что пользователь еще не был полностью аутентифицирован.
Поэтому я переключился на использование AuthenticationSuccessHandler
. Я старался придерживаться той же логики. Я пытаюсь добавить роли в токен аутентификации пользователя с помощью authentication.getAuthorities().add(...);
, но получаю сообщения об ошибках, что мой CustomAuthority
не расширяет GrantedAuthority
. Он не расширяет его, но реализует интерфейс. Мне было интересно, было ли это потому, что это было перечисление, поэтому я изменил его на класс, и я все еще получаю сообщение об ошибке. Вот код для пользовательского AuthenticationSuccessHandler
, как он у меня сейчас:
public class CustomAuthoritiesMapper implements AuthenticationSuccessHandler
{
private CustomPermissionDAO permissionsDao = new CustomPermissionDAO();
private static final String ROLE_ADMIN = "ADMIN_ACCOUNT";
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException
{
List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
List<DatabasePermission> permissionsForUser = permissionsDao.getPermissionByUsername(authentication.getName());
for (DatabasePermission permission : permissionsForUser)
{
if (ROLE_ADMIN.equals( permission.getTag() ))
{
roles.add(new CustomAuthority("ROLE_ADMIN"));
}
//Default role for all users.
roles.add(new DashboardAuthority("ROLE_EMPLOYEE"));
}
for(GrantedAuthority auth : roles)
{
authentication.getAuthorities().add(auth);
}
}
}
Я пробовал почти все комбинации всего, что только мог придумать. Я изменил List<GrantedAuthority>
на список объектов CustomAuthority. Я пытался использовать addAll(roles)
вместо добавления отдельных. Каждый раз, когда я получаю какой-то вариант этой же ошибки:
Метод add(capture#1-of ? extends GrantedAuthority) в коллекции типа неприменим для аргументов (GrantedAuthority)
И код CustomAuthority:
public class CustomAuthority implements GrantedAuthority
{
private String name;
public CustomAuthority(String name)
{
this.name = name;
}
public String getAuthority() {
return name;
}
}
Любая помощь приветствуется.
Судя по «связанным вопросам», похоже, что authentication.getName() здесь может не работать, но я хочу выяснить, почему я не могу добавить разрешения, которые я хочу добавить, к полномочиям пользователя, прежде чем я решу эту проблему.