Expected Behavior
I want to be able to have a custom login page with my own template for logout and error states, while still having the auto redirect to the provider login page if only one registration exists.
Current Behavior
Setting a custom login page stops the auto redirect functionality and there's no easy way to re-enable it.
Context
A workaround would be to duplicate what the following snippet does myself:
final LoginUrlAuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint(loginUrl);
registerAuthenticationEntryPoint(http, entryPoint);
Comment From: jzheaux
@JoakimLofgren thanks for the suggestion. To make sure I'm understanding your use case correctly, would the following work?
List<String> registrations;
@GetMapping("/my-custom-login")
public String login() {
if (registrations.size() == 1) {
String registrationId = registrations.get(0);
return "redirect:/saml2/authenticate/" + registrationId;
}
// ... return custom template
}
If that wouldn't work, can you help me understand why not?
Comment From: JoakimLofgren
Hey @jzheaux
Never did a controller, just a addViewController and a template like explained here:
https://www.baeldung.com/spring-security-login#login-form
Was hoping to get an option like:
saml2
.loginPage("/login")
.autoRedirect()
But yeah, I assume that creating a controller myself instead of using a ViewControllerRegistry would probably work.
Comment From: jzheaux
I see, @JoakimLofgren. Generally, the DSL should stay as minimal as possible, and it doesn't seem like such a feature would be so common as to want to place it there.
Never did a controller, just a
addViewControllerand a template
Instead of having the redirect functionality in a controller, you could have a custom AuthenticationEntryPoint:
public AuthenticationEntryPoint entryPoint() {
AuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint("/login");
return (request, response, exception) -> {
if (registrations.size() == 1) {
String registrationId = registrations.get(0);
response.sendRedirect("/saml2/authenticate/" + registrationId);
} else {
entryPoint.commence(request, response, exception);
}
};
}
// ...
http
.saml2Login(saml2 -> saml2
.authenticationEntryPoint(entryPoint())
);
Then, I believe you'd still be able to use your ViewControllerRegistry to wire your /login endpoint.
As far as I can tell, we've got a couple of solutions here, so I'm going to close this ticket. However, please feel free to re-open if you feel like there's more to discuss.
Comment From: JoakimLofgren
Thanks for the suggestions :)
Comment From: JoakimLofgren
saml2.authenticationEntryPoint appears to be private :(
https://github.com/spring-projects/spring-security/blob/master/config/src/main/java/org/springframework/security/config/annotation/web/configurers/AbstractAuthenticationFilterConfigurer.java#L72
Comment From: jzheaux
@JoakimLofgren, my apologies. The entry points are configured via the .exceptionHandling DSL method:
http
.saml2Login(Customizer.withDefaults())
.exceptionHandling(exception -> exception
.authenticationEntryPoint(entryPoint())
);