Spring Security @PreAuthorize аннотация с AuthenticationSuccessEvent - PullRequest
0 голосов
/ 30 мая 2020

У меня базовая c аутентификация, и я хочу войти / сделать что-то при успешном входе в систему, но AuthenticationSuccessEvent запускается, даже если у этой РОЛИ нет разрешения, мне нужно получить доступ к этому методу HTTP. Как я могу регистрировать / делать что-то ТОЛЬКО если я могу получить доступ к этому методу HTTP с разрешением.

@Component("authorization")
public class AuthorizationUtils {

    public boolean hasPermission(final String permission) {
        Collection<? extends GrantedAuthority> authorities = getUserDetails().getAuthorities();
        return authorities.contains(new SimpleGrantedAuthority(permission));
    }

    public static UserDetails getUserDetails() {
        SecurityContext securityContext = SecurityContextHolder.getContext();
        Authentication authentication = securityContext.getAuthentication();
        if (authentication != null && authentication.getPrincipal() instanceof UserDetails) {
            return (UserDetails) authentication.getPrincipal();
        }
        return null;
    }

}
public class AuthenticationEventListener implements ApplicationListener<AuthenticationSuccessEvent> {

  @Autowired
  private HttpServletRequest request;

  @Override
  public void onApplicationEvent(AuthenticationSuccessEvent event) {

    String username = ((UserAccountDetails) event.getAuthentication().getPrincipal()).getUsername();

    log.trace("Account with username : {} successfully log in!", username);

    System.out.println(request.getHeader("Authorization"));
  }
  @GetMapping("/permission")
  @PreAuthorize("@authorization.hasPermission('edit.helloworld123')")
  public String editHelloWorld(){
    return "Welcome to permission edit.helloWorld!";
  }

1 Ответ

0 голосов
/ 30 мая 2020

Авторизация - это не то же самое, что аутентификация. Аутентификация - это то, может ли пользователь успешно войти в систему или нет. Авторизация связана с тем, имеет ли пользователь, вошедший в систему, достаточно прав для выполнения метода. Таким образом, даже если пользователь успешно вошел в систему (т.е. происходит AuthenticationSuccessEvent), если у него недостаточно прав для выполнения метода, метод все равно не выполняется.

Что вам действительно нужно, так это обнаружить авторизацию событие успеха, но теперь вы обнаруживаете событие успешной аутентификации, что совершенно разные вещи.

Чтобы включить для публикации sh события успешной авторизации после пользователя, который достаточно разрешений для успешного выполнения защищенного метода, вы должны включить setPublishAuthorizationSuccess из MethodInterceptor.

Из docs , чтобы переопределить настройки по умолчанию, связанные с безопасностью метода, вы можете расширить GlobalMethodSecurityConfiguration:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    @Override
    public MethodInterceptor methodSecurityInterceptor(MethodSecurityMetadataSource methodSecurityMetadataSource) {
        MethodInterceptor result = super.methodSecurityInterceptor(methodSecurityMetadataSource);
        ((MethodSecurityInterceptor) result).setPublishAuthorizationSuccess(true);
        return result;
    }
}

И AuthorizedEvent будет опубликован после того, как у пользователя будет достаточно разрешений для выполнения защищенного метода. Поэтому создайте ApplicationListener для прослушивания и обработки:

@Component
public class MyEventListener implements ApplicationListener<AuthorizedEvent> {

    @Override
    public void onApplicationEvent(AuthorizedEvent event) {
        //Handle the AuthorizedEvent event here......
    }
}
...