简体   繁体   中英

Error: Full authentication is required to access this resource when using @PreAuthorize

I am trying to implement a authentication using Spring Boot, JWT with Roles

I have the error:

full authentication is required to access this resource

when send POST request to "http://localhost:8080/api/profile/edit_user_detail" (with authoziration header)

Below is my Controller

@Controller
@CrossOrigin(origins = "*",maxAge = 3600)
@RequestMapping("/api/profile")
public class UserAPI {

    @Autowired
    UserRepository userRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    QARepository qaRepository;
    @Autowired
    DiscussRepository discussRepository;
    @Autowired
    AnnouncementRepository announcementRepository;

    @PostMapping(value = {"/edit_user_detail"})
    @PreAuthorize("hasRole('ROLE_USER')")
    public ResponseEntity<?> editInfo(@RequestBody Map map) throws ParseException {
        String username = map.get("username").toString();
        String display_name = map.get("display_name").toString();

        User user = userRepository.findByUserName(username).get(0);
        user.setuDigitalName(display_name);
       
        userRepository.save(user);

        return ResponseEntity.ok("Updated");
    }

But when i remove the line

@PreAuthorize("hasRole('ROLE_USER')")

then i can success POST the request and edited successfully the user (I have checked in database)

Also this is my EntryPoint (to catch Exception)

@Component
public class AuthEntryPointJwt implements AuthenticationEntryPoint {
    private static final Logger log = LoggerFactory.getLogger(AuthEntryPointJwt.class);
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        log.error("Authorized error: " + e.getMessage());
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,"Error: Unauthorized");
        e.printStackTrace();
    }
}

And this is my Configuration file

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ConfigAuthenticate extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServices userDetailsServices;

    @Autowired
    private AuthEntryPointJwt unauthorizeHandler;

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

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsServices).passwordEncoder(passwordEncoder());
    }

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

        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }

}

I think there are a problem with configuration in WebSecurityConfigurerAdapter , i have try to

  • Change @PreAuthorize("hasRole('ROLE_USER')") to @PreAuthorize("hasRole('USER')")
  • Check the JWT Token in header, also the ROLE in database

but it's still not work, anybody have solution

Try removing .antMatchers("/**").permitAll() , and add these lines to your:

application.yml

logging:
  level:
    org.springframework.security: TRACE

or application.properties

logging.level.org.springframework.security=TRACE

And you could see the information about your user like this:

AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]]

You can rely on Granted Authorities in order to determine user's roles


Because you're setting .antMatchers("/**").permitAll() before .anyRequest().authenticated() , I'm not so sure whether you validated the user successfully or not. If not, then the AnonymousAuthenticationFilter will create an anonymous user for you. And in case you don't add @PreAuthorize("hasRole('USER')") , the FilterSecurityInterceptor , bases on .antMatchers("/**").permitAll() , will allow the request gets through it and accesses the controller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM