2012-05-30 55 views
8

Chúng tôi đang phát triển một ứng dụng di động với jQuery dành cho thiết bị di động và muốn xác thực người dùng bằng chương trình phụ trợ mùa xuân 3.1.x được thiết lập chính xác với bảo mật mùa xuân.Bảo mật mùa xuân: lập trình đăng nhập

Yêu cầu POST được gửi đến phần phụ trợ (sử dụng $ .post của jQuery) chứa tên người dùng và mật khẩu, sau đó máy chủ xác minh xem thông tin đăng nhập có chính xác không và đăng nhập người dùng.

Máy chủ có vẻ đã đặt đúng xác thực trong SecurityContext, tuy nhiên khi chúng tôi thực hiện yêu cầu thứ hai cho máy chủ ($ .get tới trang yêu cầu đăng nhập), các chi tiết bảo mật dường như không được ghi nhớ và ẩn danh mã thông báo dường như nằm trong ngữ cảnh.

Đây là phương pháp trong điều khiển để xử lý các (kiểm tra mật khẩu lấy ra cho ngắn gọn) đăng nhập:

@RequestMapping(value = "/login", method = RequestMethod.POST, produces = "application/json") 
@ResponseBody 
public Map<String, String> login(@RequestParam String username, @RequestParam String password, HttpServletRequest request) { 
    Map<String, String> response = new HashMap<String, String>(); 

    User u = userService.findByAccountName(username); 

    if (u != null && u.hasRole("inspector")) { 
     UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); 
     try { 
      Authentication auth = authenticationManager.authenticate(token); 
      SecurityContextHolder.getContext().setAuthentication(auth); 

      response.put("status", "true"); 
      return response; 
     } catch (BadCredentialsException ex) { 
      response.put("status", "false"); 
      response.put("error", "Bad credentials"); 
      return response; 
     } 
    } else { 
     response.put("status", "false"); 
     response.put("error", "Invalid role"); 
     return response; 
    } 
} 

Đây là phương pháp khác mà chúng tôi nhận được userdetails ra khỏi bối cảnh:

@RequestMapping(value = "/project", method = RequestMethod.GET) 
@ResponseBody 
public String getProjects(HttpSession session) { 

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
    User u = userService.findByAccountName(((UserDetails) authentication.getPrincipal()).getUsername()); 
... 

mùa xuân cấu hình bảo mật:

<global-method-security pre-post-annotations="enabled"/> 
<http use-expressions="true" auto-config="true"> 

    <form-login login-processing-url="/static/j_spring_security_check" login-page="/" 
       authentication-failure-url="/?login_error=t"/> 

    ... 
    <intercept-url pattern="/api/**" access="permitAll"/> 
    ... 
    <remember-me key="biKey" token-validity-seconds="2419200"/> 
    <logout logout-url="/logout"/> 
</http> 

<authentication-manager alias="authenticationManager"> 
    <authentication-provider user-service-ref="udm"> 
     <password-encoder hash="md5"/> 
    </authentication-provider> 
</authentication-manager> 

này nên làm việc theo vào tài liệu bảo mật mùa xuân và các tài nguyên trực tuyến khác. Bất kỳ ý tưởng về những gì có thể là sai?

+0

SecurityContextChính sách giữ nguyên mặc định là ThreadLocal. Mỗi yêu cầu được xử lý trong chủ đề mới (thực sự không phải tất cả trong trường hợp của hồ bơi thread, nhưng điều này không quan trọng) và có nó riêng của bản sao của bối cảnh giữ threadlocal. Vì vậy, xác thực của bạn mà ws thiết lập trong phương thức đăng nhập không thể được truy cập trong phương thức getProjects (vì nó nằm trong một luồng khác). Bạn nên lưu thông tin xác thực của bạn ở một số nơi (ví dụ http session) và khôi phục đối tượng xác thực mỗi lần yêu cầu mới đến máy chủ (có thể trong bộ lọc servlet) –

+1

Kiểm tra http://stackoverflow.com/questions/3923296/user-granted -authorities-are-always-role-anonymous – axtavt

+0

Tôi đã triển khai chức năng chính xác này bằng câu trả lời xuất sắc được liên kết bởi axtavt. –

Trả lời

11

Tôi bị nhầm lẫn bởi cấu hình của bạn. Bạn đã thực hiện bộ điều khiển đăng nhập của riêng mình, nhưng có vẻ như bạn đang sử dụng hình thức đăng nhập của Spring Security. Gần đây tôi đã thực hiện đăng nhập ajax với Spring Security + jquery. Thay vì viết bộ điều khiển riêng của mình, tôi chỉ cần triển khai thực hiện AuthenticationSuccessHandler và AuthenticationFailureHandler của riêng mình để trả về các câu trả lời của json mà tôi cần. Chỉ cần mở rộng SimpleUrlAuthenticationSuccessHandler và SimpleUrlAuthenticationFailureHandler trọng các phương pháp onAuthenticationSuccess và onAuthenticationFailure trong mỗi lớp, một cái gì đó đơn giản như ....

public void onAuthenticationSuccess(HttpServletRequest request, 
     HttpServletResponse response, Authentication authentication) 
     throws IOException, ServletException { 
    response.getWriter().println("{\"success\": true}"); 
} 

public void onAuthenticationFailure(HttpServletRequest request, 
     HttpServletResponse response, AuthenticationException exception) 
     throws IOException, ServletException { 
    response.getWriter().println("{\"success\": false}"); 
} 

Sau đó, bạn có thể cấu hình các yếu tố hình thức đăng nhập với một cái gì đó giống như ...

<form-login login-processing-url="/static/j_spring_security_check" login-page="/" 
      authentication-success-handler-ref="ajaxAuthenticationSuccessHandler" 
      authentication-failure-handler-ref="ajaxAuthenticationFailureHandler" 
      authentication-failure-url="/?login_error=t"/> 
+0

Điều này làm việc hoàn hảo ... cảm ơn. – HDave

+0

Rất vui khi được giúp đỡ, vui lòng đánh dấu câu trả lời của tôi là đã chấp nhận – hyness

+0

Tôi sẽ làm như vậy nếu tôi có thể .... – HDave

Các vấn đề liên quan