我正在尝试通过JWT获得春季安全性,以与某个应用一起使用。我已经阅读了许多教程和示例,但是没有什么适合我的用例。我们不通过用户名/密码进行授权,我们使用twilio验证手机号码,然后我想创建一个简单的JWT令牌,以手机号码为主题。我已经能够做到这一点
这是/ api / v1 / jwt中存在的简单端点
@GetMapping("/jwt")
fun jwt(@RequestParam(value = "number", required = true) number: String): String? {
val jwtToken = Jwts.builder().setSubject(number).claim("roles", "user").setIssuedAt(Date()).signWith(SignatureAlgorithm.HS256, Base64.getEncoder().encodeToString("secret".toByteArray())).compact()
return jwtToken
}
返回有效的JWT令牌。
尽管我的安全配置不再起作用,现在所有端点似乎都受到保护,
@Configuration
@EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {
@Bean
override fun authenticationManagerBean(): AuthenticationManager {
return super.authenticationManagerBean()
}
override fun configure(web: WebSecurity) {
web.ignoring().antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**");
}
override fun configure(http: HttpSecurity) {
http.csrf()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/v1/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(JwtFilter(), UsernamePasswordAuthenticationFilter::class.java)
}
}
JWT筛选器
@Throws(IOException::class, ServletException::class)
override fun doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain) {
val request = req as HttpServletRequest
val response = res as HttpServletResponse
val authHeader = request.getHeader("authorization")
if ("OPTIONS" == request.method) {
response.status = HttpServletResponse.SC_OK
chain.doFilter(req, res)
} else {
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
throw ServletException("Missing or invalid Authorization header")
}
val token = authHeader.substring(7)
try {
val claims = Jwts.parser().setSigningKey(Base64.getEncoder().encodeToString("secret".toByteArray())).parseClaimsJws(token).body
request.setAttribute("claims", claims)
} catch (e: SignatureException) {
throw ServletException("Invalid token")
}
chain.doFilter(req, res)
}
}
}
似乎过滤器随时会被命中,无论其上方的许可如何。不应在任何api / v1 / auth /路径上忽略过滤器吗?我想我错过了一些东西。
第二个问题,有没有一种方法可以应用此过滤器而不必在之前或之后添加且不扩展https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.html
编辑:antPathRequestMatcher不会触发配置,但是我什至添加了Websecurity配置的路径,我得到了此日志记录
2019-12-30 14:44:44.792 DEBUG 81181 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /api/v1/auth/request?number=5555555 has an empty filter list```
在您的配置中,您有:
override fun configure(http: HttpSecurity) {
http.csrf()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/v1/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(JwtFilter(), UsernamePasswordAuthenticationFilter::class.java)
}
我看到以下内容:
.antMatchers("/api/v1/auth/**").permitAll()
.anyRequest().authenticated()
因此,Spring Security正在检查所有请求的身份验证。在我的春季配置中,我通常这样做:
.antMatchers("/swagger-ui.html","/webjars/**","/swagger-resources/**", "/v2/**","/csrf")
.permitAll()
.antMatchers("/**")
.authenticated()
因此,请尝试通过设置更改配置:
override fun configure(http: HttpSecurity) {
http.csrf()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/v1/auth/**").permitAll()
.antMatchers("/**").authenticated()
.and()
.addFilterBefore(JwtFilter(), UsernamePasswordAuthenticationFilter::class.java)
}
关于第二个问题:
第二个问题,有没有一种方法可以应用此过滤器在之前或之后添加且不扩展https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.html
坦率地说,在这种情况下,我将通过使用Spring Security和Spring Security OAuth Sprign Security jwt继续使用OAuth / OpenID。
在这种情况下,我将创建一个ResourceServer配置类和一个AuthorizationServer配置类(或者可以将同一类用作AuthorizationServer和ResourceServer);一个很好的例子在这里https://www.baeldung.com/spring-security-oauth-jwt
我希望它有用
天使