Spring boot - własna adnotacja

0

Cześć,

chciałbym stworzyć adnotację, której będę mógł używać w kontrolerach i zwróci mi aktualnie zalogowanego użytkownika przez token JWT z nagłówka Authorization. Coś jak @AuthenticationPrincipal. Jak mogę opakować tą logikę w adnotację? Są jakieś dobre przykłady?

Pozdrawiam

0

Ale sama adnotacja przecież nie może nic zrócić. na pewno wiesz co chcesz zrobić?

0

Może nie tyle adnotacja, co chcę wstrzyknąć jakaś logikę do argumentu oznaczonego przez moją adnotację.

0

Możesz użyć AOPa do tego

0

Okej, czy taki aspekt może mieć informację o aktualnych nagłówkach zapytania? Bo to mnie powstrzymuje

0

HandlerMethodArgumentResolver to jest dokładnie to czego szukałem :)

0

@VeloxDigitis:
Z tego co pamiętam możesz też do metody kontrola dodać HttpServletRequest i wtedy pobrać token z requestu...

0

@scibi92: Tak właśnie robiłem, ale wtedy w każdej metodzie http musiałbym pobierać token i potem odpowiednio go parsować, żeby dostać użytkownika. Teraz mogę zrobić coś takiego:

    @GetMapping("account")
    public ResponseEntity<?> getAccount(User user) {
        return ResponseEntity.ok(user.getLogin());
    }
0

No tak, ale przeciez to nie jest problem napisac jakiegoś Utilsa (tutal może być nawet metoda statyczna) i po prostu skorzystac z tego w każdej klasie w której trzeba - po to sa podziały na klasy i metody :)
Oczywiście nie mówie że zawsze ręczne przetwarzanie requestu jest najlepsze, to tylko sugestia że można to zrobić rozsądnie ;)

0

Jasne, że można, tylko po co? To rozwiązanie wydaje się dużo bardziej eleganckie i czytelne :)

0

Jesli dobrze zrozumialem, to to co chcemy osiagnac to to:

@GetMapping("/")
public String get(@Username String username) {
    return "Hello " + username;
}	

Potrzebujemy

  1. Adnotacje mark'ujaca parametr.
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Username {
}
  1. Resolver do Springa, ktory bedzie umial wyciagnac to z headera. Ja tutaj dalem na przykald prosty basic auth (bez obslugi edge casow etc), raczej poradzisz sobie ze zmiana pod swoj use-case.
public class UsernameResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(Username.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {
        String authHeader = nativeWebRequest.getHeader("Authorization");
        String encodedPart = authHeader.split("Basic ")[1];
        String decodedPart = new String(Base64.getDecoder().decode(encodedPart));
        return decodedPart.split(":")[0];
    }
}
  1. Trzeba resolver zarejestrowac w kontenerze
@Configuration
public class WebConf implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new UsernameResolver());
    }
}

voilà

1 użytkowników online, w tym zalogowanych: 0, gości: 1