Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security doesn't post to provided login processing url

For some weird reason, I cannot hit the controller that is registered to handle login posts. I just get redirected to this silly image that is in my resources folder:

https://localhost:8443/images/piggy-bank.jpeg

Here is my controller.

@RequestMapping(value = "/login/process", method = RequestMethod.POST)
public String loginPost(HttpSession session, Authentication authentication) {

    String client_id = (String) session.getAttribute("client_id");

    if (client_id.equals(Constants.TRUSTED_CLIENT)) {

        //TODO:
        /*
         * 1. Generate an access_token
         * 2. Save to database
         * 3. Form redirect url with all necessary tokens
         * 4. Return redirect url string
         */

        return "redirect:" + Constants.REDIRECT_TRUSTED_CLIENT; 

    }

    long userId = AuthenticationUtils.getAuthenticatedUserId(authentication);
    return "/user/" + userId;
}

Here is my security configuration:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("customUserDetailsService")
    UserDetailsService userDetailsService;

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
                authorizeRequests()
                .antMatchers("/","/sign_up","/resources/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .permitAll()
                .loginPage("/login")
                .loginProcessingUrl("/login/process")
                .defaultSuccessUrl("/")
                .failureUrl("/access_denied")
                .and()
            .csrf()
                .and()
            .exceptionHandling()
                .accessDeniedPage("/access_denied")
                .and()
            .logout()
                .permitAll();

    }
}

And here's the view:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head lang="en">

        <title>Spring App</title>

        <!--/*/ <th:block th:include="fragments/headerinc :: head"></th:block> /*/-->
    </head>

    <body>
        <div class="container">
            <!--/*/ <th:block th:include="fragments/header :: header"></th:block> /*/-->

            <div id="mainWrapper">
                <div class="login-container">
                    <div class="login-card">
                        <div class="login-form">
                            <form th:action="@{/login/process}" method="post" class="form-horizontal">
                                <div th:if="${param.error != null}">
                                    <div class="alert alert-danger">
                                        <p>Invalid username and password.</p>
                                    </div>
                                </div>
                                <div th:if="${param.logout != null}">
                                    <div class="alert alert-success">
                                        <p>You have been logged out successfully.</p>
                                    </div>
                                </div>
                                <div class="input-group input-sm">
                                    <label class="input-group-addon" for="username"><i class="fa fa-user"></i></label>
                                    <input type="text" class="form-control" id="username" name="username" placeholder="Enter Username" />
                                </div>
                                <div class="input-group input-sm">
                                    <label class="input-group-addon" for="password"><i class="fa fa-lock"></i></label>
                                    <input type="password" class="form-control" id="password" name="password" placeholder="Enter Password" />
                                </div>
                                <input type="hidden" name="${_csrf.parameterName}"   value="${_csrf.token}" />

                                <div class="form-actions">
                                    <input type="submit"
                                           class="btn btn-block btn-primary btn-default" value="Log in"/>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

Inspecting my network data, I see that the form post to /login/process was successful and the server responded fine!

Request URL:https://localhost:8443/login/process
Request Method:POST
Status Code:302 Found
Remote Address:[::1]:8443

The log during spring startup also affirms the registration of url "/login/post" to the aforementioned controller. Corresponding log:

2016-04-21 20:44:30.725  INFO 25290 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/login/process],methods=[POST]}" onto public java.lang.String com.springapp.controllers.UserController.loginPost(javax.servlet.http.HttpSession,org.springframework.security.core.Authentication)

The situation may be something more insidious, because I can't seem to be redirected to even the defaultSuccessURL page, i.e. the index ("/"). The same is the case (i.e. loginProcessingURL and defaultSuccessfulURL not redirecting) exists even if I use the default out-of-box login view. Is there something wrong with my jsp view? Am I missing some security configuration?

However, manually entering /user/{id} OR any other url successfully lands me to the target url as long as I'm properly authenticated. What does that mean?

Finally here is the 'header.html' and 'headerinc.html' thymeleaf fragments which are inserted in all my jsp:

header.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

    <link href="../../static/css/app.css"
          th:href="@{css/app.css}" rel="stylesheet" media="screen"/>
    <link href="../../static/css/bootstrap.css"
          th:href="@{css/bootstrap.css}" rel="stylesheet" media="screen"/>
    <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css"
          th:href="@{/webjars/font-awesome/4.2.0/font-awesome.css}" rel="stylesheet" media="screen"/>

</head>
<body>

<div class="container">
    <div th:fragment="header">
        <nav class="navbar navbar-default">
            <div class="container-fluid">
                <div class="navbar-header">
                    <a class="navbar-brand" href="#" th:href="@{/}">Home</a>
                    <ul class="nav navbar-nav">
                        <!-- if logged in, then display -logout, else display -login, -Sign up. -->
                        <div th:with="currentUser=${#httpServletRequest.userPrincipal?.name}">

                            <div th:if="${currentUser != null}">
                                <form th:action="@{/logout}" method="post">
                                    <input type="submit" value="Log out"/>
                                </form>
                            </div>

                            <div th:if="${currentUser == null}">
                                <li><a href="#" th:href="@{/login}">Log in</a></li>
                                <li><a href="#" th:href="@{/sign_up}">Sign up</a></li>
                            </div>

                            <!-- This is to simply test some authentication logic-->
                            <a href="#" th:href="@{/users}">All Users</a>
                        </div>
                    </ul>
                </div>
            </div>
        </nav>

        <div class="jumbotron">
            <div class="row text-center">
                <div class="">
                    <h2>Spring Framework Example..</h2>

                    <h3>Spring Boot Web App</h3>
                </div>
            </div>
            <div class="row text-center">
                <img src="../../static/images/NewBannerBOOTS_2.png" width="400"
                     th:src="@{/images/piggy-bank.jpeg}"/>
            </div>
        </div>
    </div>
</div>
</body>
</html>

headerinc.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en" th:fragment="head">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" media="screen" />

    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <link href="../static/css/guru.css"
          th:href="@{/css/guru.css}" rel="stylesheet" media="screen"/>
</head>
<body>

</body>
</html>
like image 521
apil.tamang Avatar asked Apr 22 '16 01:04

apil.tamang


People also ask

What is default target URL in Spring Security?

default-target-url If not set, the default value is "/" (the application root).

Is WebSecurityConfigurerAdapter deprecated?

From Spring Boot 2.7, WebSecurityConfigurerAdapter is deprecated.

Does Spring Security use default login form?

In this configuration Spring Security will render a default log in page. Most production applications will require a custom log in form. The configuration below demonstrates how to provide a custom log in form.


2 Answers

This line:

.loginProcessingUrl("/login/process")

tells Spring Security to process the submitted credentials when sent the specified path and, by default, redirect user back to the page user came from. It will not pass the request to Spring MVC and your controller.

Maybe what you want instead of a request mapping is a custom AuthenticationSuccessHandler.

like image 120
holmis83 Avatar answered Nov 04 '22 16:11

holmis83


I had also the same issue very recently.
In my case, I had to add this code

<public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/js/**","/assets/**", "/css/**");
}

Note:
Be careful not to use .anyRequest() here, like in

web.ignoring().antMatchers("/js/**","/assets/**", "/css/**").anyRequest()

Because that also gave me a lot of problems ...

like image 42
jorgehernand Avatar answered Nov 04 '22 17:11

jorgehernand