Java 用于验证正文内容的spring引导安全身份验证
我想对post请求主体密钥-值对中的一个进行身份验证,但我想在拦截器/过滤器的帮助下进行同样的验证。如何执行此操作?您可以创建一个自定义请求筛选器,用于检查请求:Java 用于验证正文内容的spring引导安全身份验证,java,spring,spring-boot,spring-security,spring-security-rest,Java,Spring,Spring Boot,Spring Security,Spring Security Rest,我想对post请求主体密钥-值对中的一个进行身份验证,但我想在拦截器/过滤器的帮助下进行同样的验证。如何执行此操作?您可以创建一个自定义请求筛选器,用于检查请求: public class MyFilter implements OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, Fil
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);
}
}
通过重写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;
} ```
你可以试试这个过滤器
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;
}
@Bean
公共筛选器注册bean simpleFilter(){
FilterRegistrationBean registrationBean=新的FilterRegistrationBean();
setFilter(新的SimpleFilter());
返回注册bean;
}
让我知道这是否有效。SecurityContextHolder.getContext().getAuthentication().getPrincipal()正在返回null,如果我这样做,有什么想法吗?如果我在预处理中进行的身份验证失败,如何发送401 Http错误响应?更新了响应。请检查。问题是我无法读取此文件中的请求正文。由于我需要检查请求正文中的一个参数,请参考此链接…您的身份验证是如何发送的?在请求主体中?我希望,通常身份验证令牌是通过头发送的。是的,我可以通过头访问经过身份验证的用户。String user=SecurityContextHolder.getContext().getAuthentication().getName(),但我需要使用此用户验证其中一个post正文参数。我的类扩展了相关编辑中的OncePerRequestFilter,并且我已重写了doFilterInternal方法。这有关系吗,我的意思是它与实现Filter类不同吗?问题是,在调用do Filter之前,我无法提取请求正文,并且我得到了错误:响应已经提交。您不能调用
response。在filterChain.doFilter(请求,响应)`之后调用sendError(..)。因为后一个调用将响应写入outputstream,因此出现错误。我发布的第二个解决方案似乎在本地为我工作。请使用req.getReader().lines().collect(Collectors.joining(System.lineSeparator()))
获取请求正文,然后重试。这表明已为此请求调用了getReader()。请参阅此:请参阅此: