title: Spring security custom AuthenticationToken
body: <p>I implement custom <code>AuthenticationProvider</code> and return custom <code>AuthenticationToken</code>.</p>
  
  <pre><code>@Override
      public Authentication authenticate(Authentication authentication) throws AuthenticationException {
          String username = authentication.getName();
          String password = authentication.getCredentials().toString();
          DBUser dbUser = userDao.getUserLDAP(username);
          //check password
          return new CustomAuthenticationToken(dbUser, password, grantedAuthorities);
      }
  </code></pre>
  
  <p>CustomAuthenticationToken :</p>
  
  <pre><code>public class CustomAuthenticationToken extends AbstractAuthenticationToken {
      private DBUser principal;
      private String credential;
      public CustomAuthenticationToken(DBUser dbUser, String password, Collection&lt;? extends GrantedAuthority&gt; authorities) {
          super(authorities);
          this.setDetails(dbUser);
          this.principal = dbUser;
          this.credential = password;
          this.setAuthenticated(true);
      }
  //getters, setters
  }
  </code></pre>
  
  <p>But while i try do in controller: </p>
  
  <pre><code>@GetMapping("/user/current")
      public ResponseEntity&lt;Object&gt; currentUser(@AuthenticationPrincipal DBUser dbUser){
          return ResponseEntity.ok(dbUser);
      }
  </code></pre>
  
  <p><code>dbUser</code> is null, becouse in <code>AuthenticationPrincipalArgumentResolver</code> in method <code>resolveArguments</code> </p>
  
  <pre><code>public Object resolveArgument(MethodParameter parameter, 
            ModelAndViewContainer mavContainer, NativeWebRequest 
            webRequest, WebDataBinderFactory binderFactory) throws 
       Exception {
          Authentication authentication = 
              SecurityContextHolder.getContext().getAuthentication();
          if (authentication == null) {
              return null;
          } else {
              Object principal = authentication.getPrincipal();
  </code></pre>
  
  <p><code>authentication.userAuthentication</code> is instance of <code>UsernamePasswordAuthenticationToken</code> (not my returned custom). </p>
  
  <p>How can i put to token detailes and then get it form security context?</p>
  
  <p>I use spring security oauth2 + jwt.</p>
  
  <p>Security config:</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Autowired
      private CustomAuthenticationProvider authenticationProvider;
  
      @Override
      protected void configure(AuthenticationManagerBuilder auth) {
          auth.authenticationProvider(authenticationProvider);
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http.authorizeRequests()
                  .anyRequest()
                  .authenticated()
                  .and()
                  .sessionManagement()
                  .sessionCreationPolicy(SessionCreationPolicy.NEVER);
      }
  
      @Bean
      public PasswordEncoder passwordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
      @Override
      public void configure(WebSecurity web) throws Exception {
          web.ignoring().antMatchers("/v2/api-docs",
                  "/configuration/ui",
                  "/swagger-resources",
                  "/configuration/security",
                  "/swagger-ui.html",
                  "/webjars/**");
      }
  
      @Override
      @Bean
      public AuthenticationManager authenticationManagerBean() throws Exception {
          return super.authenticationManagerBean();
      }
  }
  </code></pre>
  
  <p>OAuth config:</p>
  
  <pre><code>@Configuration
  @EnableAuthorizationServer
  public class OAuthConfig extends AuthorizationServerConfigurerAdapter {
  
      private static final String CLIENT_ID = "client";
      private static final String CLIENT_SECRET = "pwd";
  
      @Autowired
      @Qualifier("authenticationManagerBean")
      private AuthenticationManager authenticationManager;
  
      @Bean
      public JwtAccessTokenConverter tokenEnhancer() {
          JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
          converter.setSigningKey(Keys.PRIVATE_KEY);
          converter.setVerifierKey(Keys.PUBLIC_KEY);
          return converter;
      }
  
      @Bean
      public JwtTokenStore tokenStore() {
          return new JwtTokenStore(tokenEnhancer());
      }
  
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
          endpoints.authenticationManager(authenticationManager)
                  .tokenStore(tokenStore())
                  .accessTokenConverter(tokenEnhancer());
      }
  
      @Override
      public void configure(AuthorizationServerSecurityConfigurer security) {
          security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
      }
  
      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
          clients.inMemory()
                  .withClient(CLIENT_ID)
                  .secret(new BCryptPasswordEncoder().encode(CLIENT_SECRET))
                  .scopes("read", "write")
                  .authorizedGrantTypes("authorization_code", "refresh_token", "password")
                  .scopes("openid")
                  .autoApprove(true)
                  .accessTokenValiditySeconds(20000)
                  .refreshTokenValiditySeconds(20000);
      }
  }
  </code></pre>
  
  <p>Thx.</p>