- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 Spring Security 开发具有 JWT 授权的 Spring Boot Rest API。我希望所有请求都通过过滤器来验证 JWT token ,除了应生成 jwt token 的 /authenticate
请求。但是使用下面的代码,/authenticate
请求也被过滤器拦截,因此失败并返回 401。请让我知道下面的代码中缺少什么。
JwtTokenFilter 类
@Component
public class JwtTokenFilter extends OncePerRequestFilter
{
@Autowired
private UserService jwtUserDetailsService;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException
{
final String requestTokenHeader = request.getHeader("Authorization");
String username = null;
String jwtToken = null;
// JWT Token is in the form "Bearer token". Remove Bearer word and get
// only the Token
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer "))
{
jwtToken = requestTokenHeader.substring(7);
try
{
username = jwtTokenUtil.getUsernameFromToken(jwtToken);
}
catch (IllegalArgumentException e)
{
System.out.println("Unable to get JWT Token");
}
catch (ExpiredJwtException e)
{
System.out.println("JWT Token has expired");
}
}
else
{
logger.warn("JWT Token does not begin with Bearer String");
}
// Once we get the token validate it.
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null)
{
UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);
// if token is valid configure Spring Security to manually set
// authentication
if (jwtTokenUtil.validateToken(jwtToken, userDetails))
{
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// After setting the Authentication in the context, we specify
// that the current user is authenticated. So it passes the
// Spring Security Configurations successfully.
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
JwtConfig 类
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class JwtConfigurer extends WebSecurityConfigurerAdapter
{
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private UserService jwtUserDetailsService;
@Autowired
private JwtTokenFilter jwtRequestFilter;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
{
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
{
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception
{
// We don't need CSRF for this example
httpSecurity.csrf().disable().
// dont authenticate this particular request
authorizeRequests().antMatchers("/authenticate").permitAll().
// all other requests need to be authenticated
anyRequest().authenticated().and().
// make sure we use stateless session; session won't be used to
// store user's state.
exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Add a filter to validate the tokens with every request
httpSecurity.addFilterAfter(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
Controller 类
@RestController
@CrossOrigin
public class JwtAuthenticationController
{
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private UserService userDetailsService;
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(@RequestBody User authenticationRequest) throws Exception
{
authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());
final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
final String token = jwtTokenUtil.generateToken(userDetails);
User u = new User();
u.setUsername(authenticationRequest.getUsername());
u.setToken(token);
return ResponseEntity.ok(u);
}
private void authenticate(String username, String password) throws Exception
{
try
{
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
}
catch (DisabledException e)
{
throw new Exception("USER_DISABLED", e);
}
catch (BadCredentialsException e)
{
throw new Exception("INVALID_CREDENTIALS", e);
}
}
}
最佳答案
我为此苦苦挣扎了两天,最好的解决方案是 Tom answer与我的 SecurityConfig
上的此设置相结合:
override fun configure(http: HttpSecurity?) {
// Disable CORS
http!!.cors().disable()
// Disable CSRF
http.csrf().disable()
// Set session management to stateless
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//Add JwtTokenFilter
http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter::class.java)
}
关于java - 在 Spring Boot 安全性中,无法跳过登录 URL 的 OncePerRequestFilter 过滤器(主要是在初始登录期间获取 JWT token ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58938733/
文档说 org.springframework.web.filter.OncePerRequestFilter “保证每个请求只执行一次”。在什么情况下,每个请求可能会多次执行过滤器? 最佳答案 Un
我有一个 Spring 应用程序(不使用 Spring boot)部署到 tomcat 我尝试使用 OncePerRequestFilter 在给定条件下的特定 URL 上返回错误 401 (Http
我已经发现了一些与此主题相关的问题,但我发现没有一个问题能阐明此主题。 显然 OncePerRequestFilter 确保请求在过滤器链中仅通过一次过滤器,但我不清楚何时会发生相反的情况。 很高兴看
正如文档所说: Filter base class that aims to guarantee a single execution per request dispatch, on any ser
我想从OncePerRequestFilter类访问一个spring组件,但是当我访问服务时得到空指针,我认为原因是配置。 我认为由于配置,过滤器在spring调度程序servlet之前被调用。有什么
我有一个 JWTAuthFilter,它扩展了 OncePerRequestFilter 我正在验证 token 。 validateToken方法抛出自定义异常(CredentialsChanged
public class FlashMapFilter extends OncePerRequestFilter { @Override @SuppressWarnings("unch
我有一个基本的 SpringBoot 2.0.5.RELEASE 应用程序。使用Spring Initializer、JPA、嵌入式Tomcat、Thymeleaf模板引擎,打包为可执行JAR文件。
我有一个扩展 OncePerRequestFilter 的过滤器。当我使用 management.port=8081 和 server.port=8080(或任何不同的端口)时,我的过滤器不会在任何
我有一个扩展 OncePerRequestFilter 的过滤器。当我使用 management.port=8081 和 server.port=8080(或任何不同的端口)时,我的过滤器不会在任何
我已经在我的 springboot 应用程序中实现了 OncePerRequestFilter,但是在添加过滤器 swagger 之后没有打开它给出了 401 错误(这是显而易见的)。我的问题是如何在
我有一个简单的 OncePerRequestFilter 有几个 init-param我的 web.xml 中定义的条目,但我不知道如何从过滤器中访问它们。 getFilterConfig()返回 n
我正在尝试使用 Spring Security 开发具有 JWT 授权的 Spring Boot Rest API。我希望所有请求都通过过滤器来验证 JWT token ,除了应生成 jwt toke
我是一名优秀的程序员,十分优秀!