Ich habe versucht herauszufinden, wie das Ergebnis der Formularauthentifizierung in JSON mit Spring Security zurückgegeben werden kann.
Die von mir überprüfte Version lautet wie folgt.
Version | |
---|---|
Java | 1.8 |
Spring Boot | 1.5.10.RELEASE |
Code aus der Theorie. Bitte lesen Sie zuerst den Beispielcode.
JsonAuthConfigurer.java
package example;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
@Configuration
public class JsonAuthConfigurer extends WebSecurityConfigurerAdapter
implements AuthenticationSuccessHandler, AuthenticationFailureHandler {
private static final MediaType CONTENT_TYPE_JSON = MediaType.APPLICATION_JSON_UTF8;
@Autowired
MappingJackson2HttpMessageConverter httpMessageConverter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin() //Festlegen der Formularauthentifizierung
.successHandler(this) //Handler-Spezifikation bei erfolgreicher Authentifizierung
.failureHandler(this); //Handler-Spezifikation, wenn die Authentifizierung fehlschlägt
http.authorizeRequests().anyRequest().authenticated(); //Festlegen von Anforderungen, die eine Authentifizierung erfordern
}
// ------------------------------
// AuthenticationSuccessHandler
// ------------------------------
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException {
MyResult result = new MyResult("Erfolgreiche Authentifizierung"); //Objekt, um JSON zu sein
HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
httpMessageConverter.write(result, CONTENT_TYPE_JSON, outputMessage); //In Antwort schreiben
response.setStatus(HttpStatus.OK.value()); // 200 OK.
}
// ------------------------------
// AuthenticationFailureHandler
// ------------------------------
@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception) throws IOException {
MyResult result = new MyResult("Authentifizierungsfehler"); //Objekt, um JSON zu sein
HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
httpMessageConverter.write(result, CONTENT_TYPE_JSON, outputMessage); //In Antwort schreiben
response.setStatus(HttpStatus.UNAUTHORIZED.value()); // 401 Unauthorized.
}
// ------------------------------
/**Authentifizierungsergebnis*/
@lombok.Value
public static class MyResult {
private final String message;
}
}
Es scheint, dass Sie JSON in den Antwortinhalt mit successHandler [^ fqcn-s] und failHandler [^ fqcn-f] schreiben sollten. Im Falle eines Authentifizierungsfehlers wird der Status auf "401 Unauthorized" gesetzt.
Tips Da der Prozess zum Konvertieren von Response in JSON problemlos abgeschlossen wurde, sind hier einige Tipps aufgeführt, die mir nach dem Ausprobieren verschiedener Dinge aufgefallen sind.
MappingJackson2HttpMessageConverter
Wenn Sie JSON in den Antwortinhalt schreiben, ist es praktisch, MappingJackson2HttpMessageConverter
zu verwenden.
Außerdem wird automatisch "Content-Type: application / json; charset = UTF-8" zum Header hinzugefügt.
Autowired MappingJackson2HttpMessageConverter
@Autowired
MappingJackson2HttpMessageConverter httpMessageConverter;
Schreiben Sie JSON
httpMessageConverter.write(result, CONTENT_TYPE_JSON, outputMessage);
Übrigens, wenn Sie selbst an Response schreiben, ist dies wie folgt. [^ quote-1]
@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);
}
Wie im obigen Beispielcode wird der Code durch Implementieren der Schnittstellen verschiedener Handler in der WebSecurityConfigurer-Implementierungsklasse sauberer.
Auszug aus einem sauberen Teil
@Configuration
public class JsonAuthConfigurer extends WebSecurityConfigurerAdapter
implements AuthenticationSuccessHandler, AuthenticationFailureHandler {
//↑ Weil der Handler in dieser Klasse implementiert ist...
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.successHandler(this) //← Das Argument der Handler-Spezifikation kann dies sein
.failureHandler(this); //← Das Argument der Handler-Spezifikation kann dies sein
}
//...
}
Dies ist die dritte Zertifizierungsserie. Frühere Artikel lauten wie folgt.
Ich fühle mich wie ich mich an den Frühling gewöhne.
Recommended Posts