鉴于以下应用
import java.security.Principal;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@Configuration
@RestController
public class AuthlistenerApplication {
@GetMapping("/")
public String hello(final Principal principal) {
return "Hello, " + principal.getName() + ".";
}
@Bean
public ApplicationListener<AuthenticationSuccessEvent> onSuccessListener() {
return (AuthenticationSuccessEvent event) -> {
System.out.println("Yeah!");
};
}
@Bean
public ApplicationListener<AuthenticationFailureBadCredentialsEvent> onBadCredentialsListener() {
return (AuthenticationFailureBadCredentialsEvent event) -> {
System.out.println("Oh no...");
};
}
public static void main(String[] args) {
SpringApplication.run(AuthlistenerApplication.class, args);
}
}
在 Spring Boot 1.5.9.RELEASE上运行此命令会触发AuthenticationSuccessEvent
一个AuthenticationFailureBadCredentialsEvent
事件,具体取决于用户是否使用正确的密码。
这些事件都不会在2.0.0.BUILD-SNAPSHOT上触发,也可能不会在 Milestone 上触发。这是一个测试来证实这一点:
import java.util.Base64;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.rule.OutputCapture;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@TestPropertySource(properties = {
"security.user.name = testuser",
"security.user.password = testpassword",
"spring.security.user.name = testuser",
"spring.security.user.password = testpassword",})
public class AuthlistenerApplicationTests {
@Rule
public OutputCapture output = new OutputCapture();
@Autowired
TestRestTemplate restTemplate;
@Test
public void logsSuccess() throws Exception {
final HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + Base64.getEncoder().encodeToString("testuser:testpassword".getBytes()));
headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
final ResponseEntity<String> r = restTemplate
.exchange("/", HttpMethod.GET, new HttpEntity<>(headers), String.class);
assertThat(r.getStatusCode(), is(equalTo(HttpStatus.OK)));
assertThat(r.getBody(), is(equalTo("Hello, testuser.")));
assertThat("Output did not contain 'Yeah!'", output.toString(), containsString("Yeah!"));
}
@Test
public void logsFailure() throws Exception {
final HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + Base64.getEncoder().encodeToString("testuser:fump".getBytes()));
headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
final ResponseEntity<String> r = restTemplate
.exchange("/", HttpMethod.GET, new HttpEntity<>(headers), String.class);
assertThat(r.getStatusCode(), is(equalTo(HttpStatus.UNAUTHORIZED)));
assertThat("Output did not contain 'Oh no...'", output.toString(), containsString("Oh no..."));
}
}
我使用快照进行测试,因为测试使用新的旧属性来配置用户(请参阅#10963)。
我已经检查过它是否DefaultAuthenticationEventPublisher
仍然是的一部分SecurityAutoConfiguration
,是的,它是。所以我认为这些事件仍然应该被发布。