Bảo mật với spring (Tiếp theo)

Chào các bạn, như trong bài trước, tôi đã trình bày về vấn đề bảo mật trong spring, để tiếp tục, tôi trình bày về vấn đề xây dựng một hệ thống Single Sign On.

I. Giới thiệu

Trong Spring Security, frameword đã cung cấp cho chung ta thư viện oauth2, các bạn có thể tham khảo ví dụ ở đây. Tuy nhiên, theo sự tìm hiểu của tôi, thì tôi mới chỉ custom nó được ở mức có thể xây dựng Single Sign On cho các hệ thông được xây dựng bằng spring khác, còn về việc xây dựng cho các ngôn ngữ khác thì khá khó khăn. Do đó, tôi nhận thấy sử dụng thư viện này với bài toán của tôi thì không ổn. Bài toán của tôi được đặt ra như sau: - Sử dụng được cho nhiều hệ thống được xây dựng bằng các framework và ngôn ngữ khác nhau. - Sử dụng thông qua rest api. Từ những yêu cầu trên, hôm nay tôi sẽ giới thiệu về cách tôi đã làm.

II. Hướng giải quyết.

Từ những yêu cầu trên, cách tôi sử lý mỗi khi có request yêu cầu xác thực như sau:

1. Kiểm tra origin đã được đăng ký với hệ thống chưa? (Kiểm tra trong cơ sở dữ liệu).

  • Ở bước này, tôi lưu danh sách các origin vào 1 danh Hash, với key là tên origin đã được chuẩn hóa.
  • Khi có 1 request mới, tôi chuẩn hóa sau đó kiểm tra origin mới đã tồn tại hay chưa?
  • Khi thay đổi thông tin 1 origin nào đó, tôi xây dựng 1 hàm để update thông tin.

2. Kiểm tra access_token.

  • Access_token là 1 key được hệ thống sinh một cách ngẫu nhiên và duy nhất.
  • Được lưu ở header của request.
  • Mỗi access_token có 1 thời gian đợi xác định. Ví dụ, thời gian đợi là 24 tiếng. Thời gian của mỗi request của người dùng cách nhau hơn 24 tiếng thì access_token này sẽ bị hủy, và yêu cầu người dùng đăng nhập lại.
  • Nếu access_token này còn thời gian và chính xác, hệ thông sẽ trả lại các thông tin của người dùng.
  • Nếu access_token này không chính xác hoặc hết thời gian, hệ thống sẽ yêu cầu đăng nhập lại.

Vậy làm thế nào để có thể kiểm tra các access_token của mỗi request? Trong hệ thống này, tôi sử dụng Filter. Được sử dụng như sau:

protected void configure(HttpSecurity http) throws Exception {
	//Todo code
	http.addFilterAfter(new MyFilter(), BasicAuthenticationFilter.class);
}

Và lớp MyFilter là một lớp được kế thừa từ GenericFilterBean

 public class VbeeFilter extends GenericFilterBean {
    private ConfigRepository configRepository;

    public VbeeFilter() {
        super();
    }

    public VbeeFilter(ConfigRepository configRepository) {
        super();
        this.configRepository = configRepository;
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;         
        //Todo code
        chain.doFilter(request, response);
    }
}

Note: Để có thể thực hiện các task sau khi filter, ta bắt buộc phải khai báo chain.doFilter(request, response);

Trên đây là cách tôi xây dựng phần xác thực quyền cho từng request và tôi đã xây dựng.

Cảm ơn các bạn!

*Smt