Ошибка: для доступа к этому ресурсу требуется полная аутентификация JWT - PullRequest
0 голосов
/ 20 апреля 2020

У меня проблема с доступом к пути / user , несмотря на то, что я предоставляю токен носителя в заголовке авторизации.

enter image description here

ниже фрагмента кода для конфигурации безопасности:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
        securedEnabled = true,
        jsr250Enabled = true,
        prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${ldap.url}")
    private String ldapUrl;

    @Value("${ldap.domain}")
    private String ldapDomain;

    @Value("${ldap.userSearchBase}")
    private String ldapSearchBase;

    @Value("${ldap.userGroupSearch}")
    private String ldapGroupSearch;

    @Value("${ldap.searchFilter}")
    private String ldapSearchFilter;

    @Value("${ldap.managerDn}")
    private String ldapManagerDn;

    @Value("${ldap.managerPassword}")
    private String ldapManagerPassword;

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf()
                .disable()
                .cors()
                .disable()
                .exceptionHandling()
                .authenticationEntryPoint(unauthorizedHandler)
                .and()
                .authorizeRequests()
                .antMatchers("/api/auth/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);;
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider())
                .ldapAuthentication()
                .userSearchBase(ldapSearchBase)
                .groupSearchBase(ldapGroupSearch)
                .userSearchFilter(ldapSearchFilter)
                .ldapAuthoritiesPopulator(ldapAuthoritiesPopulator())
                .contextSource()
                .url(ldapUrl)
                .managerDn(ldapManagerDn)
                .managerPassword(ldapManagerPassword);
    }


    private LdapAuthoritiesPopulator ldapAuthoritiesPopulator() {
        return new LdapAuthoritiesPopulator() {
            @Override
            public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData,
                                                                                String username) {
                return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
            }
        };
    }

    @Bean
    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(ldapDomain, ldapUrl);
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        return provider;
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }




}

Токен успешно генерируется при публикации на URL: http://localhost: 8085 / api / auth / generatetoken

Но я не авторизован, несмотря на то, что предоставляю правильный токен (посмотрите на рисунок выше), когда я хочу получить доступ к другому ресурсу, например пользователям (запрашивающему путь / user ).

Ниже двух контроллеров, один для генерации токенов, другой просто отображает имя пользователя:

Генерация токенов:

@RestController
@RequestMapping("/api/auth")
public class AuthController {

    @Autowired
    AuthenticationManager authenticationManager;


    @Autowired
    JwtTokenProvider tokenProvider;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @PostMapping("/generatetoken")
    public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
        if(loginRequest.getUsername().isEmpty() || loginRequest.getPassword().isEmpty()) {
             return new ResponseEntity(new ApiResponse(false, MessageConstants.USERNAME_OR_PASSWORD_INVALID),
                     HttpStatus.BAD_REQUEST);
        }
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        loginRequest.getUsername(),
                        loginRequest.getPassword()
                )
        );
        String jwt = tokenProvider.generateToken(authentication);
        return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @PostMapping("/validatetoken")
    public ResponseEntity<?> getTokenByCredentials(@Valid @RequestBody ValidateTokenRequest validateToken) {
         String username = null;
         String jwt =validateToken.getToken();
         if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
                username = tokenProvider.getUsernameFromJWT(jwt);
              //If required we can have one more check here to load the user from LDAP server
             return ResponseEntity.ok(new ApiResponse(Boolean.TRUE,MessageConstants.VALID_TOKEN + username));
           }else {
               return new ResponseEntity(new ApiResponse(false, MessageConstants.INVALID_TOKEN),
                       HttpStatus.BAD_REQUEST);
           }

    }
}

Отображение имени пользователя:

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping
    public ResponseEntity<String> getUser(){
        return new ResponseEntity<String>("Amine", HttpStatus.OK);
    }
}

Я благодарен за любую помощь.

...