How do I fix Unauthorized error: Full authentication is required to access this resource in Kotlin Springboot Web Service

174 views Asked by At

I am trying to implement Role Based Authentication and Authorization in an LMMS but after configuration, I made signup request with Postman and I kept on having Unauthorized Error

: Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed in public edu.eduforge.lmms.controller.AuthApi(org.springframework.security.authentication.AuthenticationManager,edu.eduforge.lmms.repository.UserRepository,org.springframework.security.crypto.password.PasswordEncoder,edu.eduforge.lmms.security.jwt.JwtUtils): [Error in object 'edu.eduforge.lmms.controller.AuthApi': codes []; arguments []; default message [Parameter specified as non-null is null: method edu.eduforge.lmms.controller.AuthApi.<init>, parameter authenticationManager]] ]
Unauthorized error: Full authentication is required to access this resource

I have check online and try chatGPT but the stay wont go

Here is my Code

@RestController
            @RequestMapping("/api_v1/auth")
            class AuthApi(
            private val authenticationManager: AuthenticationManager,
            private val userRepository: UserRepository,
            private val passwordEncoder: PasswordEncoder,
            private val jwtUtils: JwtUtils
        ) {
 @PostMapping("/signin")
            fun authenticateUser(@Valid @RequestBody loginRequest: LoginRequest): ResponseEntity<*>{
                val authentication: Authentication = authenticationManager.authenticate(
                    UsernamePasswordAuthenticationToken(loginRequest.username, loginRequest.password)
                )
            // Setting the context for current user
                SecurityContextHolder.getContext().authentication = authentication
            //        Getting jwt token for current user
                val jwt: String = jwtUtils.generateJwtToken(authentication)

                val userDetails: UserDetailsImpl = authentication.principal as UserDetailsImpl
                val roles: List<String> = userDetails.authorities.stream()
                    .map { item -> item.authority }
                    .collect(Collectors.toList())

                return ResponseEntity.ok(JwtResponse(
                    jwt,
                    userDetails.getId(),
                    userDetails.username,
                    userDetails.getEmail(),
                    roles
                ))

                @PostMapping("/signup")
                fun registerUser(@Valid @RequestBody signupRequest: SignupRequest): ResponseEntity<*>{
                    if(userRepository.existsByUsername(signupRequest.username)){
                        return ResponseEntity.badRequest()
                            .body( MessageResponse("Error: Username is already taken!"))
                    }

                    if(userRepository.existsByEmail(signupRequest.email)){
                        return ResponseEntity.badRequest()
                            .body( MessageResponse("Error: Email is already taken!"))
                    }

                    //create new User's account
                    val strRoles: Set<String> = signupRequest.roles
                    var roles: MutableSet<Role> = HashSet();
                    if(strRoles ==null){
                        roles.add(Role(appEnums.ERole.USER_ANONYMOUS))
                    }else{
                        strRoles.forEach { role ->
                            run {
                                if (role == "admin") {
                                    roles.add(Role(appEnums.ERole.USER_ADMIN))
                                }
                                else if (role == "student"){
                                    roles.add(Role(appEnums.ERole.USER_STUDENT))
                                } else if(role == "instructor"){
                                    roles.add(Role(appEnums.ERole.USER_INSTRUCTOR))
                                }
                                else{
                                    roles.add(Role(appEnums.ERole.USER_ANONYMOUS))
                                }
                            }
                        }
                    }

                    val user = User().apply{
                        firstName = signupRequest.firstName
                        lastName = signupRequest.lastName
                        username = signupRequest.username
                        email = signupRequest.email
                        password = passwordEncoder.encode(signupRequest.password)
                        roles = roles
                    }

                    //saving to database
                    userRepository.save(user)
                    return ResponseEntity.ok(MessageResponse("User registered successfully!"))
                }
            }
        }

 @Configuration
        @EnableWebSecurity
        @EnableMethodSecurity(
        //    secureEnable = true
        //    jsr250Enabled = true
            prePostEnabled = true
        )
        class WebSecurityConfig(
            private val userDetailsService: UserDetailsServiceImpl,
            private val unauthorizedHandler: AuthEntryPointJwt

        ) {
            @Bean
            fun authenticationJwtTokenFilter(): AuthTokenFilter {
                return AuthTokenFilter();
            }

            @Throws(Exception::class)
            fun configure(auth: AuthenticationManagerBuilder?){
                auth?.userDetailsService(userDetailsService)?.passwordEncoder(passwordEncoder())
            }

            @Bean
            @Throws(Exception::class)
            fun authenticationManagerBean(authConfiguration: AuthenticationConfiguration):       AuthenticationManager? {
                return authConfiguration.authenticationManager
            }

            @Bean
            fun passwordEncoder(): PasswordEncoder {
                return BCryptPasswordEncoder();
            }

            @Bean
            fun configure(http: HttpSecurity): DefaultSecurityFilterChain? {
                http.cors().and().csrf().disable()
                    .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                    .authorizeHttpRequests().requestMatchers("/api_v1/auth/**").permitAll()
                    .requestMatchers("/api_v1/test/**").permitAll()
                http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter::class.java)
                return http.build()

            }

        }

        @Component
        class AuthEntryPointJwt : AuthenticationEntryPoint {
                @Throws(IOException::class, ServletException::class)
                override fun commence(request: HttpServletRequest?, response: HttpServletResponse?, authException: AuthenticationException?) {
                    //SC_UNAUTHORIZED is 401 status code
                    println("Unauthorized error: ${authException?.message}")
                    response?.sendError(HttpServletResponse.SC_UNAUTHORIZED,"Error: Unauthorized")
                }
        }

How do I fix "Unauthorized error: Full authentication is required to access this resource in Kotlin Springboot Web Service" ?

0

There are 0 answers