0

I have a spring boot application with spring security configured. I have redirected the login request to http://localhost:8000 where I'm running my front-end on a python server. Now when I try to post the login to my springboot application, it doesn't work. Even when I try from my postman, it says 405 error. How can I get this working. It works from /login if I put it as html in the same project but not from the python server or postman. What is the difference.

"message": "Request method 'POST' not supported", "path": "/login"

Form Data

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

    <title>Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />


</head>
<body>


<!-- Add page specific code/html START -->

<div class="container">
    <h1 th:text="#{welcome.message}"></h1>

    <form class="form-signin" name="loginForm" th:action="@{/login}" action="/login" method="POST">
        <h2 class="form-signin-heading">Please sign in</h2>
        <label for="username" class="sr-only">Email address</label>
        <input type="text" name="username" id="username" class="form-control" placeholder="Username" required="required" autofocus="autofocus" />
        <label for="password" class="sr-only">Password</label>
        <input type="password" name="password" id="password" class="form-control" placeholder="Password" required="required" />

        <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    </form>

</div> <!-- /container -->


</body>
</html>

HTML code hosted on photon server

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Assessment App</title>

    <link href="../css/bootstrap.min.css" rel="stylesheet">
    <link href="../css/main.css" rel="stylesheet">

</head>
<body>

    <div class="container-fluid">
        <div class="panel panel-default main-header">
            <div class="panel-body">
                <div class ="pull-left">Assessments</div>
            </div>
        </div>
        <div class="row">
            <div class="login-container col-md-4 col-md-offset-4 col-sm-10 col-sm-offset-1 col-xs-12 col-xs-offset-0">
                <div class="panel panel-login">
                    <div class="panel-heading">
                        <div class="panel-title">Sign In</div>
                    </div>

                    <div class="panel-body">
                        <form id="loginform" class="form-horizontal" role="form">

                            <div class="input-group assessment-input-group">
                                <span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
                                <input id="login-username" type="text" class="form-control" name="username" value="" placeholder="Username">
                            </div>

                            <div class="input-group assessment-input-group">
                                <span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
                                <input id="login-password" type="password" class="form-control" name="password" placeholder="Password">
                            </div>

                            <div class="form-group">
                                <div class="col-sm-12 controls">
                                    <input class="btn btn-primary" type="submit" value="Login">
                                </div>
                            </div>
                        </form>
                        <div class="login-form-error-text hidden">Invalid credentials</div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="../javascript/jquery-3.3.1.min.js"></script>
    <script src ="../javascript/bootstrap.min.js"></script>
    <script src="../javascript/lodash.min.js"></script>
    <script src="../javascript/login.js"></script>
</body>
</html>

Corresponding js

$(document).ready(function () {


    $('#loginform').submit(function (event) {
        event.preventDefault();       
        $.ajax({
            url : 'http://localhost:8080/j_spring_security_check',
            type : 'POST',
            contentType : 'application/json',
            data : JSON.stringify({ j_username :  $('#login-username').val(), j_password : $('#login-password').val() }),
            success : function () {
                window.location.href = '../html/assessment.html';
            },  
            error : function () {
                event.preventDefault();
                alert('failed');
            }
        });
    });

    $('.form-tab-header').on('click', function () {
        $('.login-form-error-text').addClass('hidden');
        $('.form-tab-header').removeClass('active');
        $(this).addClass('active');
        $('.form-horizontal').addClass('hidden');
        $('.' + $(this).attr('id') + '-content').removeClass('hidden');
    });
});

Security Config

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${ldap.urls}")
    private String ldapUrls;

    @Value("${ldap.base.dn}")
    private String ldapBaseDn;

    @Value("${ldap.user.dn.pattern}")
    private String ldapUserDnPattern;

    @Value("${ldap.enabled}")
    private String ldapEnabled;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/login**").permitAll()
                .antMatchers("/assessments/**").fullyAuthenticated()
                .antMatchers("/").permitAll()
                .and()
                .formLogin()
                //.loginPage("http://htmlcode.s3-website.us-east-2.amazonaws.com")
                .loginPage("http://localhost:8000")
                .loginProcessingUrl("/j_spring_security_check")
                .usernameParameter("j_username")
                .passwordParameter("j_password")
                //.loginPage("/login")
                .failureUrl("/login?error")
                .permitAll()
                .and()
                .logout()
                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")
                .permitAll();

    }



    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/register");
        // .antMatchers("/assessments/**");
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        if(Boolean.parseBoolean(ldapEnabled)) {
            auth.ldapAuthentication()
                    .userDetailsContextMapper(userDetailsContextMapper())
                    .userDnPatterns(ldapUserDnPattern)
                    .contextSource()
                    .url(ldapUrls+ldapBaseDn);
        }
    }

    @Bean
    public UserDetailsContextMapper userDetailsContextMapper() {
        return new LdapUserDetailsMapper() {
            @Override
            public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
                UserDetails details = super.mapUserFromContext(ctx, username, authorities);
                return details;
            }
        };
    }

    @Bean
    CorsFilter corsFilter() {
        CorsFilter filter = new CorsFilter();
        return filter;
    }
}
user3310115
  • 1,050
  • 1
  • 11
  • 27

1 Answers1

1

You have forgotten to include csrf values.this is a security precaution mechanism to prevent cross site attacks. your have two options as a workaround :

1.Disabling CSRF:

as csrf is enabled by default, both POSTs and PUT Http methods are not allowed with CSRF enabled. for disabling it you should add this to your security config

.csrf().disable()

for example you could have such thing:

http.
.csrf().disable().
authorizeRequests()
        .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
        .and()
          .formLogin().loginPage("/login").failureUrl("/login?error")
          .usernameParameter("username").passwordParameter("password")
        .and()
          .logout().logoutSuccessUrl("/login?logout")
        .and()
          .exceptionHandling().accessDeniedPage("/403");

2.Send csrf token values :

If you are using login page with login form, we need to always include the CSRF token in the login form as a hidden parameter manually in the code:

<input
  type="hidden"
  th:name="${_csrf.parameterName}"
  th:value="${_csrf.token}" />

if you want to login by ajax you should also include these two parameters included:

first hold the values in some variables:

<script type="text/javascript">
    var csrfParameter = '${_csrf.parameterName}';
    var csrfToken = '${_csrf.token}';
</script>

then include those into

var jsonParams = {};
jsonParams['parentId'] = 1;
jsonParams[csrfParameter] = csrfToken;
// include other values pass ,user, etc.

$.ajax({
    type: 'POST',
    cache: false,
    url: /login,
    data: jsonParams,
    dataType = 'json',
    contentType = 'application/json',

    ...
});

More Information