Я работаю с веб-сайтом Spring MVC и добавляю аутентификацию в Active Directory через LDAP. Компания не хочет использовать полномочия AD для сопоставления разрешений для веб-сайта, у нас есть база данных, в которой перечислены права каждого пользователя, поэтому я пытаюсь подключиться к ней, получить разрешения и добавить их в токен аутентификации пользователя.Добавление полномочий в AuthenticationSuccessHandler
Когда я только начал, я сопоставлял полномочия группы пользователей 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) в типе Collection не применим для аргументы (GrantedAuthority)
И код CustomAuthority:
public class CustomAuthority implements GrantedAuthority
{
private String name;
public CustomAuthority(String name)
{
this.name = name;
}
public String getAuthority() {
return name;
}
}
Любая помощь будет высоко ценится.
От взгляда на «связанные вопросы» это похоже на authentication.getName() может не работать здесь, но я хочу выяснить, почему я не могу добавить разрешения, которые я хочу добавить в полномочия пользователя, прежде чем я займусь этим вопрос.
Я нашел способ взлома, чтобы сделать это в SuccessHandler, но это действительно правильный способ сделать это. Спасибо, что указал на это. – JDiPierro
На самом деле .. похоже, что использовать LdapAuthoritiesPopulator с помощью ActiveDirectoryLdapAuthenticationProvider невозможно? – JDiPierro
Вы правы (в моем ответе указывается использование LdapAuthenticationProvider, если вы хотите использовать LdapAuthoritiesPopulator). Кроме того, если вы хотите использовать ActiveDirectoryLdapAuthenticationProvider, используйте UserDetailsContextMapper. –