У меня возникла эта проблема, когда я добавил /admin
конечную точку к antMatchers("/admin").hasAuthority("ADMIN")
, она просто не будет делать запрос GET на /admin
и возвращать 200
вместо этого возвращает 403
Примечание: Я использую JWT в качестве дополнительного уровня аутентификации.
Это моя конфигурация безопасности
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/", "/health", "/authority", "/dashboard", "/users/login", "/logoutUser", "/manageEvents", "/manageAeds", "/manageReports",
"/charts", "/error", "/profile", "/authenticate/**", "/login", "/403", "/userProfile", "/deleteAed", "/users/add").permitAll()
.antMatchers("/admin").hasAuthority("ADMIN")
.antMatchers("/css/**", "/img/**", "/js/**", "/images/**", "/error_css/**", "/scss/**", "/vendor/**").permitAll()
.anyRequest().authenticated().and().
exceptionHandling().accessDeniedPage("/403").and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
Автор переместив его в permit.All()
, он будет работать, но здесь это не так.
Здесь я обрабатываю перенаправление внутри @Controller
@GetMapping("/authority")
public String getAuth(HttpServletResponse response) {
if (jwt == null) {
return "redirect:/login";
}
if (jwtTokenUtil.isTokenExpired(jwt)) {
return "redirect:/login?token=expired";
}
response.addHeader("Auth", "Bearer " + jwt);
System.out.println(loggedinUser.getRoles());
if (loggedinUser != null) {
if (loggedinUser.getRoles().equalsIgnoreCase("TILEFONITIS")) {
return "redirect:/dashboard"; //will redirect
} else if (loggedinUser.getRoles().equalsIgnoreCase("ADMIN")) {
System.out.println("Admin");
return "redirect:/admin"; //won't redirect
} else if (loggedinUser.getRoles().equalsIgnoreCase("GUEST")) {
return "redirect:/403"; // will redirect
} else {
return "redirect:/dashboard"; // will redirect
}
} else {
return "redirect:/login";
}
}
, и это мой /admin
внутри @Controller
, который никогда не вызывается.
@GetMapping("/admin")
public String getAdmin(HttpServletResponse response) {
if (jwt == null) {
return "redirect:/login";
}
if (jwtTokenUtil.isTokenExpired(jwt)) {
return "redirect:/login?token=expired";
}
response.addHeader("Auth", "Bearer " + jwt);
System.out.println("jwt" + jwt);
return "admin";
}
Странно, что с Postman меня перенаправляют!
Что мне здесь не хватает?
Редактировать: Первый звонок на /authenticate/web
, где я говорю Spring, что я аутентифицирован
authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(auth.getUsername(), auth.getPassword()));
Редактировать 2:
Для большей ясности:
Посещение из Интернета , поток:
- POST
/authenticate/web
- перенаправление с
.js
на /authority
(GET) - Не перенаправляет на
/admin
(GET) -> 403
Посещение с Почтальон , поток:
- POST
/authenticate/web
- Получите
JWT
и включите его в заголовки и сделайте GET на /authority
- Я вижу шаблон admin . -> 200
Это действительно странно, я добавляю jwt
каждый раз с response.addHeader
в поток web .
Обновление:
- Это заголовки ответа от почтальона:
plus the JWT
.
- Response headers from the web
Although now i noticed i get 302 from the web instead of a 200
and as you can see admin
page is 403
Update 2:
I've managed to break down a few things,
first of all
by having a httpSecurity.addFilterBefore
on my security
configuration means spring will look for the JWT
and add a filter before the position of the specified filter class
authorities are correctly assigned to users, so there is no issue
there
i changed hasAuthority()
to hasRole()
If you get the current user you can automatically access it's authority as shown below
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
System.out.println("Principal: "+auth.getPrincipal());
System.out.println("Authorities: "+auth.getAuthorities());
Поскольку authentication
переопределяется jwt filter
, это означает, что мне удастся получить пользователя только в том случае, если заголовок запроса содержит действительный jwt
поэтому он работал с postman
, а не с web
.
Другая проблема заключается в том, что в моем контроллере я пытаюсь добавить jwt
в заголовок response
, который будет добавлен к нему только тогда, когда контроллер завершит свою работу, я не могу попасть в следующую строку пользовательский принципал, потому что в его заголовке запроса нет jwt
.
Этот снимок экрана представляет веб-вызов и вызов от почтальона, где оба обращаются к /authority
конечной точке.
введите описание изображения здесь
- От почтальона вы видите
ADMIN
как авторитет - Но из Интернета у меня есть
ROLE_ANONYMOUS
Итак, у меня есть два варианта решения этой проблемы:
- Добавьте его в заголовок запроса.
- Защитите
REST
конечные точки с помощью JWT
и используйте пружинную безопасность по умолчанию (hasRole()
et c ) для веб-части.