Spring-Security:MySQL JDBC身份验证失败

Jef*_*eff 2 java jsp spring-security

我在这个仓库中操纵一个开源项目.该文件bank.sql是mysql中数据库的模式.这是pom.xml:

 <dependencies>

    <!-- https://mvnrepository.com/artifact/org.apache.tomcat/juli -->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>juli</artifactId>
        <version>6.0.26</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>


     <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.11</version>
   <scope>test</scope>
  </dependency>

  <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-core</artifactId>
     <version>3.2.3.RELEASE</version>
  </dependency>

  <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-web</artifactId>
     <version>3.2.3.RELEASE</version>
  </dependency>

  <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-webmvc</artifactId>
     <version>3.2.3.RELEASE</version>
  </dependency>

  <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-core</artifactId>
      <version>3.2.3.RELEASE</version>
  </dependency>

  <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>3.2.3.RELEASE</version>
  </dependency>

  <dependency>
       <groupId>org.springframework.security</groupId>
       <artifactId>spring-security-web</artifactId>
       <version>3.2.3.RELEASE</version>
  </dependency>

  <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-jdbc</artifactId>
       <version>3.2.3.RELEASE</version>
  </dependency>

  <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>5.1.6</version>
  </dependency>

  <dependency>
       <groupId>jstl</groupId>
       <artifactId>jstl</artifactId>
       <version>1.2</version>
  </dependency>

  <dependency>
       <groupId>opensymphony</groupId>
       <artifactId>sitemesh</artifactId>
       <version>2.4.2</version>
  </dependency>
 </dependencies>
Run Code Online (Sandbox Code Playgroud)

我有一个登录表格如下:

    <form name="loginForm" class="form-login"
        action="<c:url value="/j_spring_security_check" />" method="POST">
        <h2>Please sign in</h2>

        <c:if test="${not empty error}">
            <div class="alert alert-danger">${error}</div>
        </c:if>
        <c:if test="${not empty msg}">
            <div class="alert alert-info">${msg}</div>
        </c:if>

        <input type="text" class="form-control" placeholder="Username" name="username">
        <input type="password" class="form-control" placeholder="Password" name="password" />
        <button type="submit" class="btn btn-lg btn-primary btn-block" name="submit">Login</button>
        <input type="hidden" name="${_csrf.parameterName}"
            value="${_csrf.token}" />

    </form>
Run Code Online (Sandbox Code Playgroud)

文件Spring-Security.xml如下:

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <http auto-config="true" use-expressions="true">
        <intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" />
        <intercept-url pattern="/user**" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
        <intercept-url pattern="/change**" access="hasRole('ROLE_NEWUSER')" />

        <access-denied-handler error-page="/403" />

        <form-login 
            login-page="/login" 
            authentication-success-handler-ref="bankCustomAuthenticationSuccessHandler"
            authentication-failure-url="/login?error" 
            username-parameter="username"
            password-parameter="password" />
        <logout logout-success-url="/login?logout"  />
        <!-- enable csrf protection -->
        <csrf/>
    </http>

    <beans:bean id="bankCustomAuthenticationSuccessHandler"
        class="ee.mikkelsaar.bank.security.MyUrlAuthenticationSuccessHandler" />

    <authentication-manager>
        <authentication-provider>
            <password-encoder hash="sha" />
            <jdbc-user-service data-source-ref="dataSource" users-by-username-query="select username,password, enabled from users where username=?" authorities-by-username-query="select u.username, a.authority from users u, authorities a where u.username = a.username and u.username =?" />
        </authentication-provider>
    </authentication-manager>

    <beans:import resource="spring-datasource.xml" />

    <beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder">
      <beans:constructor-arg value="sha" />
    </beans:bean>


</beans:beans>
Run Code Online (Sandbox Code Playgroud)

并且有一个bean来获取数据源以提供它,Authentication-manager如下所示:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/bank" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>

</beans>
Run Code Online (Sandbox Code Playgroud)

我确信MySQL服务器正在端口3306上运行.

正确的凭证是username:Tom,password:Tom但每次我尝试使用它们登录时都会失败.我想知道,我的身份验证过程出了什么问题?

我该如何解决?

我想,也许数据源bean没有正确创建,但我不知道如何检查它?

更新:

当我添加<http security="none" pattern="/login"/>到我的Spring-Security.xml抱怨时

HTTP Status 405 - Request method 'POST' not supported for (username, password) `(Tom, tom)`, which is not a valid credential. But for a valid credential like `(Tom,Tom)` is still navigates to the login page again. 
Run Code Online (Sandbox Code Playgroud)

但它发生了

Rom*_*kiy 7

首先,在使用Spring Security之前版本4,默认的参数名称j_usernamej_password(像你提到的文章),而不是username/ password.

在Spring Security 4中,默认名称是usernamepassword,但是UsernamePasswordAuthenticationFilter绑定的默认URL 是/login和否/j_spring_security_check.

因此,在所有Spring Security版本中,您的URL和参数名称组合与默认值不匹配.

以下是如何配置针对数据库的用户名 - 密码身份验证的示例:http://www.mkyong.com/spring-security/spring-security-form-login-using-database/(适用于Spring Security 3.x) )

Spring Security 4的另一个例子(简短得多):https://spring.io/guides/gs/securing-web/

如何传递参数

基本上,如果您有基于表单的身份验证,它的工作方式如下:

  1. 用户尝试访问需要身份验证的URL; 用户缺乏身份验证
  2. Spring Security将用户重定向到登录页面
  3. 用户在该页面输入登录名和密码并提交; 在4之前的Spring Security版本的默认配置,用户名的提交j_username和密码j_password,以/j_spring_security_check
  4. Spring Security提供的UsernamePasswordAuthenticationFilter流程提交到/j_spring_security_checkURL.一旦获得请求(从登录表单),它就会提取参数(用户名/密码),将它们打包UsernamePasswordAuthenticationToken并提供给它AuthenticationManager进行身份验证.
  5. AuthenticationManager 检查访问权限(例如,JDBC可用于检查数据库)
  6. 如果验证成功(用户存在提供的名称,密码匹配),Authentication则构造结果(包含有关角色的信息),保存并AuthenticationSuccessHandler调用; 它得到了那个Authentication结果
  7. 身份验证成功后,用户将重定向回到他在步骤1中尝试访问的URL,并且此处仅执行业务逻辑控制器.