Adding user to session, spring security default login

16,367

Solution 1

You do make it complicated... :)

What you want is to add a custom authentication provider to spring's normal authentication manager. So you would configure the authentication manager like this:

    <security:authentication-manager alias="authenticationManager">
      <security:authentication-provider user-service-ref="authServiceImpl">
        <security:password-encoder ref="passwordEncoder"/>
      </security:authentication-provider>
    </security:authentication-manager>
    <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/>

Now you only need to define the authServiceImpl bean inside your spring context. You can either do this through xml or annotations (my prefered way).

@Service
public class AuthServiceImpl implements AuthService {

You need to implement the AuthService interface. Just implement to methods from the interface - should be pretty straight forward. You don't need to put things into the SecurityContextHolder yourself - spring will do that.

What you want is this:

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
     return MyUser user = myUserService.getMyUser(username);
}

Feel free to ask if you have any further questions.

EDIT: Or you could just have your UserService class implement the interface - I just did it like this because you didn't provide your UserService class.

Solution 2

or add your own AuthenticationSuccessHandler, for instance this class, i added so that i could store the username and password in session so i could login to other microservices when needed:

public class AuthenticationSuccessWithSessionHandler extends SavedRequestAwareAuthenticationSuccessHandler implements AuthenticationSuccessHandler, LogoutSuccessHandler {

    public static final String USERNAME = "username";
    public static final String PASSWORD = "password";

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        request.getSession().removeAttribute(USERNAME);
        request.getSession().removeAttribute(PASSWORD);
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        super.onAuthenticationSuccess(request, response, authentication);
        request.getSession().setAttribute(PASSWORD, request.getParameter(PASSWORD));
        request.getSession().setAttribute(USERNAME, request.getParameter(USERNAME));
    }
}

and registered it

        AuthenticationSuccessWithSessionHandler successHandler = new AuthenticationSuccessWithSessionHandler();
        http.authorizeRequests().antMatchers("/login", "/logout", "/images", "/js").permitAll().antMatchers("/feeds/**")
                .authenticated().and().formLogin()
                .successHandler(successHandler)
                .and().logout().logoutUrl("/logout").logoutSuccessHandler(successHandler).logoutSuccessUrl("/login");

note the extends SavedRequestAwareAuthenticationSuccessHandler stores the original url and restores it after successfull login.

Share:
16,367
NimChimpsky
Author by

NimChimpsky

side hustle : metriculous.network Spring is too bloated, I created my own web app framework Infrequent tweets What if programming languages were methods to eat an orange?

Updated on June 15, 2022

Comments

  • NimChimpsky
    NimChimpsky almost 2 years

    I have set up spring security to intercept correctly and prompt user with custom login page, that then authenticates correctly and adds userdetails to SecurityContextHolder.

    Supplementary to that I now want to add my own custom User object added to session whenever login is performed; so the code will look like this:

    public returnwhat? doMySupplementaryLogin() {
    
       UserDetails principal = (UserDetails) SecurityContextHolder.getContext()
                                    .getAuthentication().getPrincipal();
       MyUser user = myUserService.getMyUser(principal.getUsername());
    
       add user to what ?
    }
    

    Where will this code go? I want the nomral spring authentication to be performed and then the above code will put a MyUser object into session and then send user to the original intercepted url/viewname. I have the strong feeling I am making things more complicated than they need to be ...