Web authentication

Updated at 1691037433000

Overview

By default, the web part will not have authentication. However, this is only suitable for websites like news or blogs that do not require user login. For websites such as e-commerce, social networks, etc., we will need user authentication.

Necessary steps

To enable authentication for the web, you will need to perform the following steps:

  1. Create an interceptor class to inherit WebAuthenticationInterceptor, for example:
@Interceptor
public class AuthenticationInterceptor extends WebAuthenticationInterceptor {
   // implementation
}

If there are APIs that do not require users to log in but you still want to retrieve the userId, you can override the getCanBeUseUserIdUris method, for example:

@Interceptor
public class AuthenticationInterceptor extends WebAuthenticationInterceptor {

    @Override
    protected Set<String> getCanBeUseUserIdUris() {
        return Sets.newHashSet(
            "/",
            "/classes",
            "/classes/{code}",
            "/teachers/{teacherUuid}"
        );
    }
}

If you want to authenticate deeply into each feature, you will need to override the needToCheckPermission method, for example:

@Interceptor
public class AuthenticationInterceptor extends WebAuthenticationInterceptor {
    @Override
    protected boolean needToCheckPermission() {
        return true;
    }
}
  1. In some cases, if you use Thymeleaf and want to pass variables to all views, you can inherit the WebViewDecorator class, for example:
@EzySingleton
@AllArgsConstructor
public class ElearningWebViewDecorator extends WebViewDecorator {

    private final WebUserRoleService userRoleService;
    private final WebShoppingCartService shoppingCartService;

    @Override
    protected void decorateWithUserData(
        HttpServletRequest request,
        View view,
        UserModel user
    ) {
        Reactive.multiple()
            .register(
                "shoppingCartProductCount",
                () -> shoppingCartService
                    .getShoppingCartProductCountByOwnerId(user.getId())
            )
            .register(
                "isTeacher",
                () -> userRoleService.containsUserRole(
                    user.getId(),
                    ROLE_NAME_TEACHER
                )
            )
            .blockingConsume(map ->
                view.setVariables(map.valueMap())
            );
    }
}

Registration method

  1. To specify that a controller or a controller's function requires authentication, you need to use the @Authenticated annotation:
@Api
@Authenticated
@Controller("/api/v1")
public class ApiAccountController extends WebApiAccountController {}

You can also use the @Authenticated annotation for a function to require authentication.

  1. Sometimes, we want to assign permissions for different user groups, so we can use the @EzyFeature annotation for the controller and its corresponding functions for the features we want, for example:
@EzyFeature("teacher")
@DoPut("/account/class-lessons/{classLessonId}/content-media")
public ResponseEntity accountClassLessonsClassLessonIdContentMediaPut(
    @UserId long teacherId,
    @PathVariable long classLessonId,
    @RequestBody SaveEClassLessonContentMediaRequest request
) {
    accountValidator.validate(
        teacherId,
        request
    );
    eclassLessonService.updateClassLessonContentMedia(
        classLessonId,
        request.getContentMediaId()
    );
    return ResponseEntity.noContent();
}

Then, to assign permissions for the teacher feature, for example, we go to the role screen, such as /users/roles/teacher, and check the corresponding checkboxes.