2016-02-06 14 views
5

Tôi có một ứng dụng khởi động mùa xuân với WebSecurityConfigurerAdapter cấu hình như thế này -mùa xuân khởi động - đối tượng người dùng quay trở lại sau khi đăng nhập

http.csrf().disable() 
        .exceptionHandling() 
        .authenticationEntryPoint(restAuthenticationEntryPoint) 
        .and() 
       .authorizeRequests() 
        .antMatchers("/user/*", "/habbit/*").authenticated() 
        .and() 
       .formLogin() 
        .loginProcessingUrl("/login") 
        .permitAll() 
        .usernameParameter("email") 
        .passwordParameter("pass") 
        .successHandler(authenticationSuccessHandler) 
        .failureHandler(new SimpleUrlAuthenticationFailureHandler()) 
        .and() 
       .logout() 
        .logoutUrl("/logout") 
        .invalidateHttpSession(true); 

Tôi có thể thêm một cái gì đó giống như điều khiển của riêng tôi mà sẽ, sau khi xác thực thành công, trở về một phong tục đối tượng với một số chi tiết về người dùng đã được xác thực?

Cập nhật: Để rõ ràng, tôi đang sử dụng ứng dụng góc như ứng dụng khách. Hiện tại, tôi cần thực hiện 2 yêu cầu để gửi khách hàng của tôi tới máy chủ: 1. Yêu cầu POST tới/URL đăng nhập để xác thực. 2. Nhận yêu cầu truy xuất dữ liệu người dùng đã được xác thực.

Mục tiêu của tôi là yêu cầu 1 trở lại thông tin người dùng của tôi vì vậy tôi không phải thực hiện yêu cầu 2dn. Hiện tại, yêu cầu thứ nhất chỉ xác thực người dùng, tạo phiên trên máy chủ và gửi lại phản hồi trạng thái '200 OK' với không có dữ liệu. Tôi muốn nó trả về phản hồi thành công với dữ liệu về người dùng đã đăng nhập.

trả lời:

Câu trả lời đúng là trong ý kiến ​​vì vậy tôi sẽ viết nó ở đây: tôi cần phải chuyển hướng từ successHandler của tôi để điều khiển của tôi mà lần lượt trả về hiện đang đăng nhập thông tin người dùng (trong trường hợp của tôi điều khiển là trong url '/ user/tôi':

@Override 
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, 
             Authentication authentication) throws ServletException, IOException { 
     clearAuthenticationAttributes(request); 
     getRedirectStrategy().sendRedirect(request, response, "/user/me"); 
    } 
+0

Bạn có cần người sử dụng trong khi xử lý một số yêu cầu trong tương lai, hay bạn cần một "sự kiện" ngay tại đăng nhập? (Cả hai đều được hỗ trợ bởi spring (security) nhưng nó hoạt động theo những cách hoàn toàn khác nhau) - cho cái đầu tiên, hãy xem câu hỏi này: http://stackoverflow.com/q/8764545/280244, cho cái thứ hai có một cái nhìn tại câu hỏi này http://stackoverflow.com/questions/15493237/how-to-correctly-update-the-login-date-time-after-successful-login-with-spring-s – Ralph

+1

Tôi có một front-end góc và sau khi yêu cầu POST xác thực thành công, tôi muốn có một số chi tiết người dùng trong phản hồi, để hiển thị chúng trong trang web của tôi. – Tomas

+0

Hãy cho tôi biết: Làm cách nào bạn quản lý đăng nhập trên yêu cầu POST? –

Trả lời

7

Nếu tôi hiểu đúng vấn đề của bạn, tôi có thể đề nghị cách tiếp

Trước hết bạn phải thực hiện lớp. , sẽ chứa thông tin người dùng. Lớp này phải được thừa hưởng từ org.springframework.security.core.userdetails.User:

public class CustomUserDetails extends User { 

    public CustomUserDetails(String username, String password, 
     Collection<? extends GrantedAuthority> authorities) {    
     super(username, password, authorities); 
    } 

    //for example lets add some person data   
    private String firstName; 
    private String lastName; 

    //getters and setters 
} 

Bước tiếp theo, bạn phải tạo cho bạn thực hiện riêng của giao diện org.springframework.security.core.userdetails.UserDetailsService:

@Service 
public class CustomUserDetailService implements UserDetailsService{ 

    @Override 
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException{   

     if(StringUtils.isEmpty(userName)) 
      throw new UsernameNotFoundException("User name is empty"); 

     //if you don't use authority based security, just add empty set 
     Set<GrantedAuthority> authorities = new HashSet<>(); 
     CustomUserDetails userDetails = new CustomUserDetails(userName, "", authorities);    

     //here you can load user's data from DB or from 
     //any other source and do: 
     //userDetails.setFirstName(firstName); 
     //userDetails.setLastName(lastName); 

     return userDetails; 
    } 

} 

Như bạn thấy, lớp này chỉ có một phương pháp, nơi bạn có thể tải và đặt chi tiết người dùng tùy chỉnh. Lưu ý rằng tôi đã đánh dấu lớp này với chú thích @Service. Nhưng bạn có thể đăng ký nó trong ngữ cảnh Java-config hoặc XML của bạn.

Bây giờ, để truy cập vào dữ liệu người dùng của bạn sau khi xác thực thành công, bạn có thể sử dụng phương pháp tiếp theo, khi mùa xuân sẽ tự động chuyển chủ yếu trong phương pháp điều khiển của:

@Controller 
public class MyController{ 

    @RequestMapping("/mapping") 
    public String myMethod(Principal principal, ModelMap model){ 
     CustomUserDetails userDetails = (CustomUserDetails)principal; 
     model.addAttribute("firstName", userDetails.getFirstName()); 
     model.addAttribute("lastName", userDetails.getLastName()); 
    } 
} 

Hoặc khác một cách:

@Controller 
public class MyController{ 

    @RequestMapping("/mapping") 
    public String myMethod(ModelMap model){ 
     Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 
     CustomUserDetails userDetails = (CustomUserDetails)auth.getPrincipal(); 
     model.addAttribute("firstName", userDetails.getFirstName()); 
     model.addAttribute("lastName", userDetails.getLastName()); 
    } 
} 

Phương pháp này có thể được sử dụng ở những nơi khác, nơi Spring không tự động chuyển giao chính.

Để đi đến địa chỉ cụ thể sau khi xác thực thành công, bạn có thể sử dụng SimpleUrlAuthenticationSuccessHandler.Chỉ cần tạo ra nó trong cấu hình của bạn:

@Bean 
public SavedRequestAwareAuthenticationSuccessHandler successHandler() { 
    SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); 
    successHandler.setTargetUrlParameter("/succeslogin"); 
    return successHandler; 
} 

và sử dụng nó trong cấu hình của bạn:

http.formLogin() 
    .loginProcessingUrl("/login") 
    .permitAll() 
    .usernameParameter("email") 
    .passwordParameter("pass") 
    .successHandler(successHandler()) 

sau đó bạn có thể tạo bộ điều khiển, mà sẽ gửi phản hồi từ url speciafied:

@Controller 
@RequestMapping("/sucesslogin") 
public class SuccessLoginController{ 

    @RequestMapping(method = RequestMethod.POST) 
    public String index(ModelMap model, Principal principal){ 
     //here you can return view with response 
    } 

} 

Vì lý do, bạn có thể trả về không chỉ xem, nhưng phản ứng JSON (sử dụng chú thích @ResponseBody), hoặc một cái gì đó khác, phụ thuộc vào bạn front-end. Hy vọng điều này sẽ hữu ích.

+0

Nó sẽ giải quyết vấn đề của tôi nếu CustomUserDetails sẽ được trả lại bằng phản hồi xác thực thành công. Ví dụ. Tôi gửi một yêu cầu POST, mùa xuân đã xác thực tôi và trả về cho tôi một phản hồi thành công cùng với đối tượng CustomUserDetails này. Có thể không? – Tomas

+0

Chắc chắn, bạn có thể chuyển hướng từ 'authenticationSuccessHandler' đến bộ điều khiển của methos, và phương thức của bộ điều khiển này có thể trả về bất cứ thứ gì bạn muốn trả về. –

+0

Bạn có thể viết câu trả lời này không? Có lẽ với ví dụ? Tôi sẽ đánh dấu nó là chấp nhận. – Tomas

1

Trong câu trả lời được chấp nhận, bạn cần hai cuộc gọi để nhận dữ liệu bạn muốn. Chỉ cần trả lại dữ liệu sau khi đăng nhập trong AjaxAuthenticationSuccessHandler tùy chỉnh như thế này.

@Bean 
public AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler() { 
    return new AjaxAuthenticationSuccessHandler() { 

     @Override 
     public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { 
      response.getWriter().write(new ObjectMapper().writeValueAsString(new UserAuthenticationResponse(authentication.getName(), 123l))); 
      response.setStatus(200); 
     } 

    }; 
} 

và đăng ký successhandler:

http.successHandler(ajaxAuthenticationSuccessHandler()) 
Các vấn đề liên quan