Spring boot - własna adnotacja

Spring boot - własna adnotacja
VD
  • Rejestracja:ponad 10 lat
  • Ostatnio:10 miesięcy
  • Postów:72
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

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

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


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
VD
  • Rejestracja:ponad 10 lat
  • Ostatnio:10 miesięcy
  • Postów:72
0

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

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Możesz użyć AOPa do tego


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
VD
  • Rejestracja:ponad 10 lat
  • Ostatnio:10 miesięcy
  • Postów:72
0

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

VD
  • Rejestracja:ponad 10 lat
  • Ostatnio:10 miesięcy
  • Postów:72
0

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

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

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


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
VD
  • Rejestracja:ponad 10 lat
  • Ostatnio:10 miesięcy
  • Postów:72
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:

Kopiuj
    @GetMapping("account")
    public ResponseEntity<?> getAccount(User user) {
        return ResponseEntity.ok(user.getLogin());
    }
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
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 ;)


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
VD
  • Rejestracja:ponad 10 lat
  • Ostatnio:10 miesięcy
  • Postów:72
0

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

Leroy
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:107
0

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

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

Potrzebujemy

  1. Adnotacje mark'ujaca parametr.
Kopiuj
@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.
Kopiuj
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
Kopiuj
@Configuration
public class WebConf implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new UsernameResolver());
    }
}

voilà

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.