Search code examples
springspring-mvcspring-securityspring-roosha

spring security bad credentials even though they are correct


I am using Spring Roo and I setup my Spring Security like this (applicationContext-security.xml):

<?xml version="1.0" encoding="UTF-8"?>
<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.1.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
    <!-- HTTP security configurations -->
    <http auto-config="true" use-expressions="true" request-matcher="regex">
        <form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" />
        <logout logout-url="/resources/j_spring_security_logout" />
        <intercept-url pattern="\A/hotels\?form.*\Z" access="hasRole('ROLE_ADMIN')"/>
        <intercept-url pattern="/**" access="permitAll"/>
    </http>
    <!-- Configure Authentication mechanism -->
    <authentication-manager alias="authenticationManager">
        <!-- SHA-256 values can be produced using 'echo -n your_desired_password | sha256sum' (using normal *nix environments) -->
        <authentication-provider>
            <password-encoder hash="sha-256">
                <!-- <salt-source user-property="login"/> -->
            </password-encoder>
            <jdbc-user-service data-source-ref="dataSource"
                users-by-username-query="
                SELECT login, password, enabled
                FROM user WHERE login = ?"

                authorities-by-username-query="
                FROM user u, role r, 
                user_role ur
                WHERE u.id = ur.user
                AND r.id = ur.role
                AND u.login = ?"        
            />
            <user-service>
                <user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN" />
                <user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
</beans:beans>

Then I created a dummy user with the login johnny and the password admin, which is stored in the database like this 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918.

This is the default login page provided by the framework:

<div xmlns:spring="http://www.springframework.org/tags" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
  <jsp:directive.page contentType="text/html;charset=UTF-8" />
  <jsp:output omit-xml-declaration="yes" />
  <spring:message code="security_login_title" var="title" htmlEscape="false" />
  <util:panel id="title" title="${title}">
    <c:if test="${not empty param.login_error}">
      <div class="errors">
        <p>
          <spring:message code="security_login_unsuccessful" />
          <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
          .
        </p>
      </div>
      <br/>
    </c:if>
    <c:if test="${empty param.login_error}">
      <p>
        <!-- <spring:message code="security_login_message" /> -->
      </p>
    </c:if>
    <spring:url value="/resources/j_spring_security_check" var="form_url" />
    <form name="f" action="${fn:escapeXml(form_url)}" method="POST">
      <input type="hidden" name="test"/>
      <div>
        <label for="j_username">
          <spring:message code="security_login_form_name" />
        </label>
        <input id="j_username" type='text' name='j_username' style="width:150px" />
        <spring:message code="security_login_form_name_message" var="name_msg" htmlEscape="false" />
        <script type="text/javascript">
          <c:set var="sec_name_msg">
            <spring:escapeBody javaScriptEscape="true">${name_msg}</spring:escapeBody>
          </c:set>
          Spring.addDecoration(new Spring.ElementDecoration({elementId : "j_username", widgetType : "dijit.form.ValidationTextBox", widgetAttrs : {promptMessage: "${sec_name_msg}", required : true}})); 
        </script>
      </div>
      <br />
      <div>
        <label for="j_password">
          <spring:message code="security_login_form_password" />
        </label>
        <input id="j_password" type='password' name='j_password' style="width:150px" />
        <spring:message code="security_login_form_password_message" var="pwd_msg" htmlEscape="false" />
        <script type="text/javascript">
          <c:set var="sec_pwd_msg">
            <spring:escapeBody javaScriptEscape="true">${pwd_msg}</spring:escapeBody>
          </c:set>
          Spring.addDecoration(new Spring.ElementDecoration({elementId : "j_password", widgetType : "dijit.form.ValidationTextBox", widgetAttrs : {promptMessage: "${sec_pwd_msg}", required : true}})); 
        </script>
      </div>
      <br />
      <div class="submit">
        <script type="text/javascript">Spring.addDecoration(new Spring.ValidateAllDecoration({elementId:'proceed', event:'onclick'}));</script>
        <spring:message code="button_submit" var="submit_label" htmlEscape="false" />
        <input id="proceed" type="submit" value="${fn:escapeXml(submit_label)}" />
        <spring:message code="button_reset" var="reset_label" htmlEscape="false" />
        <input id="reset" type="reset" value="${fn:escapeXml(reset_label)}" />
      </div>
    </form>
  </util:panel>
</div>

However, when I try to log in I get a Bad credentials error. What is happening?

I can't really manage to find a way of how to debug this because it's all happening internally in spring security I guess so I can't get to know what queries are actually being made and I can't/don't know where to look to figure out why this is failing.


Solution

  • After more suffering I managed to solve it. I made the user and role entities-tables again and re-wrote the queries:

            <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query="SELECT u.login, u.password, u.enabled from users u where u.login=?"
            authorities-by-username-query="SELECT u.login, r.name FROM users u left join user_roles ur on u.id=ur.user join roles r on ur.roles=r.id WHERE u.login=?" 
            />
    

    Using two separte authentication-provide had nothing to do with my error.