2016-02-06 10 views
5

ich eine Feder Boot-Anwendung mit WebSecurityConfigurerAdapter wie diese konfiguriert habe -Frühling boot - Rückkehr Benutzerobjekt nach dem Einloggen in

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); 

Kann ich etwas hinzufügen, wie meine eigenen Controller, würde, nach erfolgreicher Authentifizierung, einen benutzerdefinierten wieder zurück Objekt mit einigen Details über den authentifizierten Benutzer?

Update: Zur Klarheit verwende ich eine eckige Anwendung als Client. Zur Zeit muss ich zwei Anfragen von meinem Client zum Server machen: 1. POST Anfrage an/Login URL für die Authentifizierung. 2. GET-Anforderung, um authentifizierte Benutzerdaten abzurufen.

Mein Ziel ist es, die erste Anfrage an mich Benutzerinformationen zurückzugeben, so muss ich nicht die 2dn Anfrage machen. Momentan authentifiziert die erste Anfrage nur den Benutzer, erstellt eine Sitzung auf dem Server und sendet eine '200 OK' Statusantwort mit keine Daten zurück. Ich möchte, dass es eine Erfolgsantwort mit Daten über den angemeldeten Benutzer zurückgibt.

Beantwortet:

Die richtige Antwort ist in den Kommentaren so werde ich es hier schreiben: ich von meinem successHandler meines Controller umleiten benötigt, was wiederum gibt die aktuell in den Benutzerinformationen angemeldet (in meinem Fall Controller ist in url '/ user/me':

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

Sie benötigen den Benutzer während einige zukünftige Anforderung bearbeitet wird, oder haben Sie ein „Ereignis“ müssen direkt beim Login? (beide werden von Feder (Sicherheit) unterstützt, aber es funktioniert auf völlig unterschiedliche Weise) - für die erste, werfen Sie einen Blick auf diese Frage: http://StackOverflow.com/q/8764545/280244, für die Sekunde schauen bei dieser Frage http://stackoverflow.com/questions/15493237/how-to-correctly-update-the-login-date-time-after-successful-login-with-spring-s – Ralph

+1

Ich habe eine eckige Front-End und nach erfolgreicher Authentifizierung POST-Anfrage möchte ich einige Benutzerdetails in der Antwort haben, um sie auf meiner Webseite zu zeigen. – Tomas

+0

Bitte sagen Sie mir: Wie haben Sie die Anmeldung bei der POST-Anfrage verwaltet? –

Antwort

7

Wenn ich dein Problem richtig verstehe, kann ich nächsten Weg vorschlagen

Zunächst einmal haben Sie Klasse zu implementieren. , die Benutzerinformationen enthalten wird. Diese Klasse muss von org.springframework.security.core.userdetails.User vererbt werden:

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 
} 

Nächster Schritt, haben Sie Sie eine eigene Implementierung von Interface org.springframework.security.core.userdetails.UserDetailsService erstellen:

@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; 
    } 

} 

Wie Sie sehen, diese Klasse hat nur eine Methode, wo Sie laden und legen Sie benutzerdefinierte Benutzerdetails fest. Beachten Sie, dass ich diese Klasse mit @Service Annotation markiert habe. Aber Sie können es in Ihrem Java-config oder XML-Kontext registrieren.

, nun Ihre Benutzerdaten nach erfolgreicher Authentifizierung zugreifen, können Sie nächsten Ansatz verwenden, wenn der Frühling automatisch Haupt in Controller-Methode übergeben wird:

@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()); 
    } 
} 

Oder eine andere Art und Weise:

@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()); 
    } 
} 

Diese Methode kann auch an anderen Stellen verwendet werden, an denen Spring Principal nicht automatisch übergibt.

Um nach erfolgreicher Authentifizierung zu einer bestimmten Adresse zu gehen, können Sie SimpleUrlAuthenticationSuccessHandler verwenden.schaffen Sie es einfach in Ihre config:

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

und verwenden Sie es in Ihrer Konfiguration:

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

nach, dass Sie Controller erstellen, diese Antwort von speciafied URL senden:

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

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

} 

Natürlich können Sie nicht nur die Ansicht zurückgeben, sondern die JSON-Antwort (unter Verwendung der @ResponseBody Annotation) oder etwas anderes hängt von Ihrem Frontend ab. Hoffe, das wird hilfreich sein.

+0

Es ist mein Problem lösen würde Wenn die CustomUserDetails mit der erfolgreichen Authentifizierungsantwort zurückgegeben würden. Z.B. Ich sende eine POST-Anfrage, Spring authentifizierte mich und gibt mir eine Erfolgsantwort zusammen mit diesem CustomUserDetails-Objekt zurück. Ist das möglich? – Tomas

+0

Sicher, Sie können von 'authenticationSuccessHandler' zu den Methoden des Controllers umleiten, und die Methode dieses Controllers kann alles zurückgeben, was Sie zurückgeben möchten. –

+0

Können Sie dies in einer Antwort schreiben? Vielleicht mit Beispiel? Ich werde es als akzeptiert markieren. – Tomas

1

In der angenommenen Antwort benötigen Sie zwei Anrufe, um die gewünschten Daten zu erhalten. Geben Sie einfach die Daten nach der Anmeldung in einem benutzerdefinierten AjaxAuthenticationSuccessHandler wie folgt zurück.

@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); 
     } 

    }; 
} 

und die successhandler registrieren:

http.successHandler(ajaxAuthenticationSuccessHandler()) 
Verwandte Themen