我正试图通过springsecurity+jwt令牌来保护我的api端点。到目前为止,令牌生成器和验证程序运行良好。当我使用 AuthenthicationPrincipal
在方法参数中获取当前值 UserDetails
. 我有我的课 Account
实施 UserDetails
,还有我的 TokenAuthenticationProvider
提供必要的 Account
基于报头持有者的令牌。
配置和控制器部分代码:
@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${spring.data.rest.basePath}")
private String apiBasePath;
private RequestMatcher protectedUrls;
private RequestMatcher publicUrls;
@NotNull
private final TokenAuthenticationProvider provider;
@PostConstruct
private void postConstruct() {
protectedUrls = new OrRequestMatcher(
// Api
new AntPathRequestMatcher(apiBasePath + "/**")
);
publicUrls = new NegatedRequestMatcher(protectedUrls);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
// when request a protected page without having authenticated
.defaultAuthenticationEntryPointFor(forbiddenEntryPoint(),
protectedUrls)
.and()
// Authenticating with rest requests
.authenticationProvider(provider)
.addFilterBefore(restAuthenticationFilter(), // injecting TokenAuthenticationProvider here
AnonymousAuthenticationFilter.class)
.authorizeRequests()
.requestMatchers(protectedUrls)
.authenticated()
.and()
// Disable server rendering for logging
.formLogin().disable()
.httpBasic().disable()
.logout().disable();
}
}
在调试模式下跟踪显示 TokenAuthenticationProvider
已正确检索 Account
. 仅当在控制器中调用时,空 Account
被退回( null
属性)
@RepositoryRestController
@RequiredArgsConstructor
@BasePathAwareController
@RequestMapping(path = "account")
class AccountController {
@GetMapping("current")
@ResponseBody
Account getCurrent(@AuthenticationPrincipal Account account) {
return account;
}
}
不过,过滤链是正确的:
servletPath:/api/account/current
pathInfo:null
headers:
authorization: Bearer eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAi...
user-agent: PostmanRuntime/7.19.0
accept: */*
cache-control: no-cache
postman-token: 73da9eb7-2ee1-43e8-9cd0-2658e4f32d1f
host: localhost:8090
accept-encoding: gzip, deflate
connection: keep-alive
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CsrfFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
TokenAuthenticationFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
我看了一些教程和问题,但无法推断出任何合适的答案。
https://octoperf.com/blog/2018/03/08/securing-rest-api-spring-security/ (这启发了我目前的实施)
https://svlada.com/jwt-token-authentication-with-spring-boot/#jwt-身份验证
@authenticationprincipal返回空用户(此用户使用 DelegatingFlashMessagesConfiguration
在我的案例中不存在)
它是否与配置或过滤器的顺序有关?
1条答案
按热度按时间uqzxnwby1#
为了@authenticationprincipal工作,我需要重写addargumentresolvers
public class UserPrincipal implements UserDetails {
}
@GetMapping(value="/me")
public User getMe(@AuthenticationPrincipal UserPrincipal currentUser){
logger.debug("name: "+currentUser.getUsername());
return this.userService.findByUsername(currentUser.getUsername());
}