当前位置: 首页 > 知识库问答 >
问题:

Spring引导身份验证问题

邹杰
2023-03-14

我有一个配置了Spring安全性的Spring启动应用程序。我已将登录请求重定向到我在 python 服务器上运行前端的 http://localhost:8000。现在,当我尝试将登录名发布到我的 springboot 应用程序时,它不起作用。即使我从邮递员那里尝试,它也说 405 错误。我怎样才能让它工作。如果我将其作为 html 放在同一个项目中,而不是从 python 服务器或邮递员中,它就可以从 /login 工作。有什么区别。

“消息”: “不支持请求方法'POST'”, “路径”: “/login”

表单数据

<!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代码

<!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>

对应的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');
    });
});

安全配置

@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;
    }
}

共有1个答案

滑景胜
2023-03-14

您忘记包含 csrf 值。这是一种防止跨站点攻击的安全预防措施机制。您有两种选择作为解决方法:

由于默认情况下启用了csrf,因此启用csrf时不允许POST和PUT Http方法。要禁用它,您应该将其添加到安全配置中

.csrf().disable()

例如,你可以有这样的东西:

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.发送csrf令牌值:

如果您使用带有登录表单的登录页面,我们需要始终在登录表单中手动将 CSRF 令牌作为隐藏参数包含在代码中:

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

如果你想通过AJAX登录,你还应该包括这两个参数:

首先保存一些变量中的值:

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

然后将这些纳入

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',

    ...
});
  • https://www.baeldung.com/spring-security-csrf
  • Ajax POST导致405(方法不允许)-Spring MVC
  • https://matthewbusche.com/2016/08/06/using-csrf-with-spring-security-and-ajax-calls/
  • Spring Security-不支持405请求方法'POST'
  • 不允许HTTP 405-Spring Boot Spring Security
  • 405 POST不允许使用的方法
  • Spring Boot Security Thymeleaf和CSRF令牌未自动注入
 类似资料:
  • 我正在开发一个Web应用程序 然而,我在尝试允许用户通过注册链接注册时遇到了一个问题。如果用户未经身份验证,则无法访问注册表的链接(“showRegistrationForm”) 有人能洞察为什么会发生这种情况吗?我在下面包含了我的安全配置中的代码片段

  • 我想对post请求主体密钥-值对中的一个进行身份验证,但我想在拦截器/过滤器的帮助下进行同样的验证。我该怎么做?

  • 我一直在尝试用Zuul、Eureka和Spring boot构建一个应用程序,最近我决定尝试登录。作为提醒,我已经配置了身份验证服务(使用OAuth2.0),并且可以使用curl成功地进行身份验证。我还可以向其他拥有受保护资源的微服务发出get请求(同样,只能使用CURL,因为我可以在身份验证头中注入令牌)。我关心的是,我想以Zuul为门户来做这件事。[![在此处输入图像说明][1]][1] 当我

  • 有人面对过这个问题吗?如果没有身份验证,spring-cloud-config-client可以很好地工作,但是如果启用了基本身份验证,相同的代码就不能工作了。 Spring Cloud Config Server应用程序。属性: Spring Cloud Config Client bootstrap.yml: 奇怪的是,记录器的输出是空白的,这意味着没有活动的配置文件。因此,很明显,这个boo

  • 我几乎没有Spring boot控制器类来公开rest web服务。每当有用户试图访问这些服务时,我需要调用一个web服务来检查用户(用户id将作为RequestHeader传递)是否被授权。如果未经授权,需要向用户显示错误页面(freemarker模板)。 我不想编写一个方法来调用身份验证Web服务,并从每个控制器方法调用它,抛出一个异常,并使用@ControllerAdvice将用户重定向到拒

  • 在Spring中使用基本身份验证时,我遇到了与HTTP响应标头“Access-Control-Allow-Origin”相关的问题。当我手动进行身份验证时,就像下面的代码一样(我使用的是REST): 一切正常,我收到以下HTTP响应: 如您所见,响应中出现了“Access-Control-Allow-Origin”。这里一切都好。我可以在ajax调用中捕捉到401错误。 但是,当身份验证自动执行时