Search code examples
spring-securityspring-authorization-server

Redirect to a user registration page from an AuthenticationSuccessHandler which then redirects back to the original SavedRequest


I have implemented federated authorization using spring authorization server as described here. I have a login form that allows the user to select which federated identity provider they would like to login with, or they can enter their username and password to authenticate with the spring authorization server,using formLogin. That part is working fine.

What I would like to implement next is for users that authenticate with one of the federated identity providers, if they haven't logged on before, then I would like to redirect them to a new user registration page instead of redirecting back to the client web application redirect endpoint. When the user registration process has completed, then I would like to redirect them back to the client web application redirect uri (with the authorization code).

I'm currently unsure how to achive this. I think that I would need to implement an AuthenticationSuccessHandler, similar to the one described here. That particular example doesn't do any redirection though or involve any additional end user interaction. What I "think" i need to do is implement an AuthenticationSuccessHandler that redirects to a User Registration form. Then when the user has completed user registration, somehow I need to use the SavedRequestAwareAuthenticationSuccessHandler to redirect back to the client webapplication redirect uri with the authorization code. How can this be done?


Solution

  • First and foremost, I'll mention that while we do have the How-to Guide you linked in Spring Authorization Server's docs, this is only because it's something we felt users would commonly want to do with SAS. However, it's really just a Spring Security feature, so we can (almost entirely) set SAS aside from the conversation.


    Generally, the flow you're referring to could fall into one of two cases in my mind:

    1. multi-step authentication
    2. post-authentication (or post-login, interstitial, speed bump, etc.)

    It really needs to be clarified which of these two options your requirements fit into. If #1, it's a security concern and you would probably want to work out how to use Spring Security's authentication concept(s) to solve it along with some authorization concepts to ensure users can't do something they shouldn't do while in the flow. If it's #2 and not a security issue but merely a user experience or business requirement, then things are simpler and there are probably many ways to solve it, depending on your preference. One way you might answer this question is to ask "Can I have a skip or I'll-do-this-later button or not?".

    In both cases though you would probably use AuthenticationSuccessHandler, but only because this is what is facilitating the redirect back to the OAuth2 Authorization Endpoint to finish the flow back to your client. It's also required because SAS itself is built on Spring Security, and exists entirely in a filter chain instead of Spring MVC endpoints.

    I'll mention however that for #1, there is one caveat for SAS that might complicate things a bit. If you want to use authorization/access rules (e.g. anyRequest().hasRole('USER')), for example if you give the user ROLE_USER only once they complete their registration step, I believe that's not currently possible in SAS. See #1415 for details.

    So before (or instead of) covering how you would actually do this, I'll ask which of these two do you feel your requirements falls into?