简体   繁体   English

AuthenticationPrincipal 返回空的 UserDetails object

[英]AuthenticationPrincipal returns empty UserDetails object

I'm trying to secure my api endpoints by spring security + jwt token.我正在尝试通过 spring 安全性 + jwt 令牌来保护我的 api 端点。 So far, the token generator and veficator work well.到目前为止,令牌生成器和验证器运行良好。 The problem arises when i use AuthenthicationPrincipal in method argument to get current UserDetails .当我在方法参数中使用AuthenthicationPrincipal来获取当前的UserDetails时,就会出现问题。 I have my class Account implement UserDetails , and my TokenAuthenticationProvider provide the necessary Account based on header bearer's token.我的 class Account实现了UserDetails ,我的TokenAuthenticationProvider提供了基于 header 持票人令牌的必要Account

Partial code of configuration and controller:部分配置代码和controller:

@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();
    }
}

Tracing in debug mode shows that the TokenAuthenticationProvider has retrieved correctly the Account .在调试模式下跟踪显示TokenAuthenticationProvider已正确检索到Account Only when called in the controller, an empty Account is returned ( null attributes)只有在controller中调用时,才会返回一个空Accountnull属性)

@RepositoryRestController
@RequiredArgsConstructor
@BasePathAwareController
@RequestMapping(path = "account")
class AccountController {
    @GetMapping("current")
    @ResponseBody
    Account getCurrent(@AuthenticationPrincipal Account account) {
        return account;
    }
}

The filter chain is correct though:过滤器链是正确的:

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
]

I looked into some tutorials and questions but could not deduce any suitable answer.我查看了一些教程和问题,但无法推断出任何合适的答案。

https://octoperf.com/blog/2018/03/08/securing-rest-api-spring-security/ (which inspires my current implementation) https://octoperf.com/blog/2018/03/08/securing-rest-api-spring-security/ (这激发了我当前的实现)

https://svlada.com/jwt-token-authentication-with-spring-boot/#jwt-authentication https://svlada.com/jwt-token-authentication-with-spring-boot/#jwt-authentication

@AuthenticationPrincipal return empty User (this one use DelegatingFlashMessagesConfiguration which does not exist in my case) @AuthenticationPrincipal 返回空用户(这个使用DelegatingFlashMessagesConfiguration在我的情况下不存在)

Does it have anything to do with the order of configuration or filters?它与配置或过滤器的顺序有关吗?

For @AuthenticationPrincipal to work I need to override addArgumentResolvers要使 @AuthenticationPrincipal 起作用,我需要覆盖 addArgumentResolvers

@Configuration
public class WevMvcConfiguration extends WebMvcConfigurationSupport {

    @Override
    protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new AuthenticationPrincipalArgumentResolver());
    }    
}

new AuthenticationPrincipalArgumentResolver() use import org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver new AuthenticationPrincipalArgumentResolver()使用导入org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver

Custom class implement UserDetails自定义 class 实现 UserDetails

public class UserPrincipal implements UserDetails {

    private static final long serialVersionUID = 1L;    
    private ObjectId id;        
    private String name;    
    private String username;    
    private String email;    
    @JsonIgnore
    private String password;    
    //constructor, getter, etc    
}

Now working really well.现在工作得很好。

@GetMapping(value="/me")    
    public User getMe(@AuthenticationPrincipal UserPrincipal currentUser){
        logger.debug("name: "+currentUser.getUsername());       
        return this.userService.findByUsername(currentUser.getUsername());
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 @AuthenticationPrincipal返回空用户 - @AuthenticationPrincipal return empty User Spring Security 4 @AuthenticationPrincipal 为空,core.annotation.AuthenticationPrincipal 但不是 web.bind.annotation.AuthenticationPrincipal - Spring Security 4 @AuthenticationPrincipal empty with core.annotation.AuthenticationPrincipal but not web.bind.annotation.AuthenticationPrincipal ReactiveSecurityContextHolder.getContext() 为空,但 @AuthenticationPrincipal 有效 - ReactiveSecurityContextHolder.getContext() is empty but @AuthenticationPrincipal works ObjectInputStream返回一个空对象 - ObjectInputStream returns an empty object @ResponseBody 返回空 object - @ResponseBody returns empty object Realm 返回空的对象列表 - Realm returns empty list of object Xpath 返回空元素 object - Xpath returns empty element object 为什么@AuthenticationPrincipal返回Authentication而不是主体对象? - Why does @AuthenticationPrincipal return the Authentication instead of the principal object? 使用Mockito返回Java 8可选对象的模拟对象返回Empty Optional - Mocking Object that returns Java 8 Optional Object with Mockito returns Empty Optional Spring安全性返回String作为主体而不是登录失败时的UserDetails? - Spring security returns String as principal instead of UserDetails on failed login?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM