简体   繁体   中英

Unauthorized error: Full authentication is required to access this resource

How can I solve JWT error in my spring code?

ERROR security.jwt.AuthEntryPointJwt - Unauthorized error: Full authentication is required to acccess this resource ERROR security.jwt.AuthTokenFilter - Cannot set user authentication {}

There is some error in my WebSecurityConfig.java file showing WebSecurityConfigurerAdapter is deprecated due which my authenticationManagerBean() is also deprecated.

Authcontroler.java Class



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

@Autowired
private UserRepo userRepo;
@Autowired
private RoleRepo roleRepo;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private JwtUtils jwtUtils;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired 
private EmailService emailService;

// POST request for adding user
@PostMapping("/register")
public ResponseEntity<?> registerUser(@Valid @RequestBody SignupRequest signupRequest) {
if (userRepo.existsByEmail(signupRequest.getEmail())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Email is already in use!"));
}

User user = new User(signupRequest.getEmail(),
signupRequest.getName(),
passwordEncoder.encode(signupRequest.getPassword()),
signupRequest.getAddress());
//signupRequest.setRole(new ArraySet<>(Set.of("ROLE_USER","")));
signupRequest.setRole("ROLE_ADMIN");
String strRoles = signupRequest.getRole();
Set<Role> roles = new HashSet<>();
if (strRoles==null) {
Role userRole = roleRepo.findByRoleName("ROLE_ADMIN")
.orElseThrow(()-> new RuntimeException("Error: role not found"));
roles.add(userRole);
}
else {
// strRoles.forEach(e->{
// switch (e) {
// case "admin":
// Role roleAdmin = roleRepo.findByRoleName("ROLE_ADMIN")
// .orElseThrow(()-> new RuntimeException("Error: role not found"));
// roles.add(roleAdmin);
// break;
//
// default:
// Role roleUser = roleRepo.findByRoleName("ROLE_USER")
// .orElseThrow(()-> new RuntimeException("Error: role not found"));
// roles.add(roleUser);
// break;
}

user.setRoles(roles);
userRepo.save(user);

emailService.sendTextEmail(user.getEmail());
return ResponseEntity
.status(201)
.body(new MessageResponse("User created successfully"));

}


// POST request for validating user
@PostMapping("/authenticate")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getEmail(),
loginRequest.getPassword()));

SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateToken(authentication);
UserDetailsImpl userDetailsImpl = (UserDetailsImpl) authentication.getPrincipal();
List<String> roles = userDetailsImpl.getAuthorities()
.stream()
.map(i->i.getAuthority())
.collect(Collectors.toList());

return ResponseEntity.ok(new JwtResponse(jwt,
userDetailsImpl.getId(),
userDetailsImpl.getEmail(),
roles));
}

@GetMapping("/")
public ResponseEntity<?> getUser() {
UserDetailsImpl userDetailsImpl = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication()
.getPrincipal();
Long id = userDetailsImpl.getId();
Optional<User> optional = userRepo.findById(id);
return ResponseEntity.ok(optional.get());
}

}

AuthEntryPointJwt.java Class


@Component
public class AuthEntryPointJwt implements AuthenticationEntryPoint {
    
    private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);
    
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {
        logger.error("Unauthorized error: {}", authException.getMessage());
        
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        
        final Map<String, Object> body = new HashMap<>();
        body.put("status", HttpServletResponse.SC_UNAUTHORIZED);
        body.put("error", "Unauthorized");
        body.put("message", authException.getMessage());
        body.put("path", request.getServletPath());
        
        final ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(response.getOutputStream(), body);
    }

}

WebSecurityConfig.java


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Autowired
    UserDetailsServiceImpl userDetailsService;
    @Autowired
    private AuthEntryPointJwt unauthorizedHandeler;
    
    @Bean
    public AuthTokenFilter authenticationJwtTokenFilter() {
        return new AuthTokenFilter();
    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        // TODO Auto-generated method stub
        authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
    
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        // TODO Auto-generated method stub
        return super.authenticationManagerBean();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // TODO Auto-generated method stub
        http.cors().and()
        .csrf()
        .disable()
        .exceptionHandling()
        .authenticationEntryPoint(unauthorizedHandeler)
        .and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeHttpRequests().antMatchers("/api/auth/**").permitAll()
        .antMatchers("/api/food/**").permitAll()
        .antMatchers("/api/cart/**").permitAll()
        .antMatchers("/api/order/**").permitAll()
        .antMatchers("/api/payment/**").permitAll()
        .antMatchers("/h2-console/**").permitAll()
        .antMatchers("/api/users/**")
        .permitAll().anyRequest().authenticated();
        
        http.headers().frameOptions().disable();
        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
//      super.configure(http);
    }

}

AuthTokenFilter.java Class


public class AuthTokenFilter extends OncePerRequestFilter {
    
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private UserDetailsServiceImpl userDetailsServiceImpl;
    
    private static final Logger LOGGER = LoggerFactory.getLogger(AuthTokenFilter.class);
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        try {
            String jwt = parseJwt(request);
            if (jwt!=null && jwtUtils.validateJwtToken(jwt)) {
                String username = jwtUtils.getUsernameFromJwtToken(jwt);
                UserDetails userDetails = userDetailsServiceImpl.loadUserByUsername(username);
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            LOGGER.error("Cannot set user authentication {}", e);
        }
        filterChain.doFilter(request, response);
    }
    
    private String parseJwt(HttpServletRequest request) {
        String headerAuth = request.getHeader("Authorization");
        if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
            return headerAuth.substring(7, headerAuth.length());
        }
        return null;
    }

}

Thankyou

You need a configuration file that allows users to talk to a login endpoint . Within this endpoint you may authenticate a user to get past the authentication barrier.

Example configuration within spring boot security:

@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/register").permitAll() // <- allow requests to this reqister endpoint
                .anyRequest().authenticated(); // <- all other requests needs full authentication;

        http.addFilterAfter(
          new AuthTokenFilter(), BasicAuthenticationFilter.class); // <- add your JWT authentication filter into the chain

    }

}

Another important step is to integrate your Filter into the filter chain of incomming requests.

You may have a look at this example: Spring Security / Getting Started . Another good resource is always Baeldung Config / Baeldung Filter

Within this configuration you can also integrate your AuthEntryPointJwt .

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