0

So I have this project, which really all I want to do is be able to have a user log in and get access to a specific page:

Security

@Configuration
@EnableWebSecurity
public class MainSecurityConfig extends WebSecurityConfigurerAdapter {


    @Resource
    private UserDetailsServiceImpl userDetailsService;

    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }


    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .csrf().disable();

        http
                .authorizeRequests()
                .antMatchers("/", "/**", "/login/**", "/index.html", "/login.html", "/components/**", "/css/**", "/js/**", "/fonts/**", "/images/**", "/.sass-cache/**", "/services.html").permitAll()
                .anyRequest().authenticated();


        http.formLogin()
                .loginPage("/login")
                .failureForwardUrl("/login.html")
                .usernameParameter("user")
                .passwordParameter("password");



    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }


    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

When I sent the /login request from angularjs as a POST I was hitting the UserDetailsServiceImpl which is good, but the username was coming in empty.

UserDetailsServiceImpl

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Resource
    private HttpSession httpSession;


    @Resource
    private UserDao userDao;


    @Override
    public UserDetails loadUserByUsername(String user) throws UsernameNotFoundException {

        User userByEmail = userDao.findUserByEmail(user);

        UserDetailsImpl userDetails = new UserDetailsImpl(userByEmail, httpSession.getId());

        return userDetails;
    }
}

So I did some googling and it said that the /login request has to be GET, which in itself confused me, should we really be plonking the username and password into the url? Or am I thinking about this wrong. Anyway, here's the angularJS code:

$scope.loginUser = function () {
    $scope.user.user = $scope.email;
    $scope.user.password = $scope.password;
    $http.get("/login", { params: {username: $scope.user.user, password: $scope.user.password}});

I no longer hit the breakpoints now within UserDetailsServiceImpl and rather I am getting a 404.

UPDATE

After updating the processing url, I now post it but the username that get's passed server-side is empty

$scope.loginUser = function () {
    $scope.user.username = $scope.email;
    $scope.user.password = $scope.password;
    $http.post("/api/authentication", $scope.user);

Everything up to here is fine, it's just when java handles it

2 Answers 2

1

If you are using Angular you have not a loginPage because you are writing a SPA and page navigation is managed by Angular itself.

You should use loginProcessingUrl that defines only the login submission url

    .and()
        .formLogin()
        .loginProcessingUrl("/api/authentication")
        .usernameParameter("username")
        .passwordParameter("password")

To submit you login you need to do a POST not a GET. Probably links mean url to access a login page not to submit.

In the example above you have to do a POST using url /api/authentication with a body containing username and password

Also if i've seen you already found the solution, i've published a project based on Spring Boot 2.0 and angular 6 (angularjs is quite outdated) with spring security and a stateful authentication (the same you were searching for)

https://github.com/ValerioMC/vforge-stateful-auth

It's just a starting point.

Sign up to request clarification or add additional context in comments.

5 Comments

Get the same issue as before with the username be sent is empty
edited answer. try to follow tutorial in the link. it's a complete example, and should help you. You will find also GitHub source code
I've already been through that exact article, they do a seperate authentication getting the user, they never actually post the details. Once authenticated they just redirect to "/login"
add related code link on GitHub. Once the user has been authenticated it's up to you to manage redirect
This is incorrect, formlogin() by default will use spring generated login page at /login if not specified differently.
0

The issue was with my AngularJS $http.post request, I solved it by adding headers for 'application/x-www-form-urlendcoded' as it is not the default header:

    $http({
        method: 'POST',
        url: '/api/authentication',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        data: 'username=' + $scope.email + '&password=' + $scope.password
    });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.