Я хочу аутентифицировать одну из пар ключ-значение тела почтового запроса, но я хочу сделать то же самое с помощью перехватчика/фильтра. Как я могу это сделать?
аутентификация безопасности весенней загрузки для проверки содержимого тела
Ответы (3)
Вы можете создать собственный фильтр запроса, который будет проверять запрос:
public class MyFilter implements OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
var user = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
// do stuff you need to do here
filterChain.doFilter(request, response);
}
}
а затем в вашем классе WebSecurityConfiguration зарегистрируйте такой фильтр
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterAfter(new MyFilter(), BasicAuthenticationFilter.class);
}
}
person
toucheqt
schedule
26.09.2020
SecurityContextHolder.getContext().getAuthentication().getPrincipal() возвращает null, если мне это нравится, есть идеи?
- person Pankaj Sharma; 27.09.2020
Вы можете расширить HandlerInterceptorAdapter и выполнять свои пользовательские операции/фильтры поверх запроса, переопределяя метод preHandle()
.
Псевдокод здесь:
@Component
public class SimpleInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// Handle your request here. In your case, authentication check should go here.
return true;
}
}
Добавьте SimpleInterceptor
в реестр для перехвата запросов.
@Configuration
@EnableWebMvc
public class SimpleMvnConfigurer implements WebMvcConfigurer {
@Autowired
SimpleInterceptor simpleInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(simpleInterceptor);
}
}
Вот и все!
РЕДАКТИРОВАТЬ 1: Чтобы отправить ответ от метода preHandle
, следуйте приведенному ниже псевдокоду:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// Handle your request here. AIn your case, authentication check should go here.
if (!isValidAuth()) {
// Populate the response here.
try {
response.setStatus(401);
response.getWriter().write("Authentication failed.");
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
return true;
} ```
person
Suman
schedule
27.09.2020
Как я могу отправить ответ об ошибке 401 Http, если аутентификация, которую я выполняю в preHandle, не удалась?
- person Pankaj Sharma; 27.09.2020
Обновил ответ. Пожалуйста, проверьте.
- person Suman; 27.09.2020
Проблема в том, что я не могу прочитать тело запроса внутри этого. Поскольку мне нужно проверить один из параметров внутри тела запроса, перейдите по этой ссылке..stackoverflow.com/questions/21193380/.
- person Pankaj Sharma; 27.09.2020
Как отправляется ваша аутентификация? В теле запроса? Я надеялся, что обычно токены аутентификации отправляются через заголовки.
- person Suman; 27.09.2020
да, я получаю доступ к аутентифицированному пользователю через. Строка user=SecurityContextHolder.getContext().getAuthentication().getName(), но мне нужно проверить один из параметров тела сообщения с этим пользователем.
- person Pankaj Sharma; 27.09.2020
Я также пробовал использовать фильтры и хотел сделать то же самое. Я получил доступ к телу в фильтре с помощью ContentCachingRequestWrapper, но проблема заключается в отправке ошибки в этом. Когда я это делаю, он говорит, что ответ уже передан
- person Pankaj Sharma; 27.09.2020
Я запутался, где мне это делать, также пытался использовать фильтры в цепочке фильтров безопасности spring, но я продолжаю получать анонимный пользователь или ноль в SecurityContextHolder.getContext().getAuthentication().getName() . Например, обратитесь к ответу toucheqt
- person Pankaj Sharma; 27.09.2020
Можете ли вы поделиться кодом о том, как вы это делаете? Потому что фильтр - это правильный способ решить вашу проблему.
- person Suman; 27.09.2020
Отредактированный вопрос
- person Pankaj Sharma; 27.09.2020
Вы можете попробовать это с помощью фильтра.
public class SimpleFilter implements Filter {
private void throwUnauthorized(ServletResponse res) throws IOException {
HttpServletResponse response = (HttpServletResponse) res;
response.reset();
response.setHeader("Content-Type", "application/json;charset=UTF-8");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
if (!isValidAuth(request)) {
throwUnauthorized(res);
}
chain.doFilter(req, res);
}
private boolean isValidAuth(HttpServletRequest request) {
// YOUR LOGIC GOES HERE.
return false;
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig arg0) {
}
}
Зарегистрируйте фильтр с помощью FilterRegistrationBean.
@Bean
public FilterRegistrationBean<SimpleFilter> simpleFilter() {
FilterRegistrationBean<SimpleFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new SimpleFilter());
return registrationBean;
}
Дайте мне знать, если это работает.
person
Suman
schedule
27.09.2020
мой класс расширяет OncePerRequestFilter в рассматриваемом редактировании, и я переопределил метод doFilterInternal. это имеет значение, я имею в виду, отличается ли он от класса реализации фильтра?
- person Pankaj Sharma; 28.09.2020
Проблема в том, что я не могу извлечь тело запроса перед вызовом do filter и получаю сообщение об ошибке: ответ уже был зафиксирован
- person Pankaj Sharma; 28.09.2020
response.sendError(..) after
filterChain.doFilter (запрос, ответ)`. Потому что последний вызов записывает ответ в outputstream и, следовательно, ошибку. Второе решение, которое я опубликовал, похоже, работает локально для меня. - person Suman   schedule 28.09.2020req.getReader().lines().collect(Collectors.joining(System.lineSeparator()))
И попробуйте. - person Suman   schedule 28.09.2020As a basic guideline, fine-grained handler-related preprocessing tasks are candidates for HandlerInterceptor implementations, especially factored-out common handler code and authorization checks. On the other hand, a Filter is well-suited for request content and view content handling, like multipart forms and GZIP compression. This typically shows when one needs to map the filter to certain content types (e.g. images), or to all requests.
- person Suman   schedule 28.09.2020