Spring安全性AJAX登录无法正常工作

时间:2015-07-17 17:29:27

标签: spring spring-mvc spring-security

我正在尝试实施AJAX登录。这是我的spring-security.xml

<http auto-config="true" use-expressions="true">
    <form-login />
</http>

<beans:bean id="pwdEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
    <beans:constructor-arg name="strength" value="11" />
</beans:bean>
<beans:bean id="appUserDetailService" class="com.mobapp.security.AppUserDetailService"></beans:bean>

<authentication-manager>
    <authentication-provider user-service-ref="appUserDetailService">
        <password-encoder ref="pwdEncoder"/>
    </authentication-provider>
</authentication-manager>

instance initializer.xml

<bean id="instanceInitializer" class="com.mobapp.appinstances.AppInstances" destroy-method="shutDownInstances">
    <constructor-arg>
        <array value-type="java.lang.String">
          <value>127.0.0.1</value>
        </array>            
    </constructor-arg>
    <constructor-arg type="java.lang.String">
        <value>127.0.0.1</value>
    </constructor-arg>
    <constructor-arg type="int">
        <value>9300</value>
    </constructor-arg>
</bean>

这是applicationContext

<context:component-scan base-package="com.mobapp.controllers" />
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" cache-period="31556926"/>
<bean id="loginSuccessHandler" class="com.mobapp.security.LoginSuccessHandler"></bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
<context:annotation-config />
<task:annotation-driven />       
<import resource="spring/instanceInitializer.xml"/>
<import resource="spring/security-context.xml"/>

这里是userdetailsservice实现

@Service

public class AppUserDetailService implements UserDetailsService{

    private static final Logger logger = Logger.getLogger(AppUserDetailService.class);    
    @Override
    public UserDetails loadUserByUsername(String loginUserName) throws UsernameNotFoundException {

        List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
        authList.add(new SimpleGrantedAuthority("ROLE_USER"));    
        System.out.println("inside load user by user name ........++++++++");
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(11);            

        return new LoggedInUser("test", passwordEncoder.encode("123"), true,true,true,true,authList);

    }

}

这是登录控制器

@RestController
public class LoginController {

   private static final Logger logger = Logger.getLogger(LoginController.class);    

   @Autowired
   private  AppInstances appInstances;

   @Autowired
   AppUserDetailService appUserDetails;   

   @RequestMapping(method = RequestMethod.POST, value = "/signup")
   public ResponseEntity<?> signup(@RequestBody SignupForm form) throws Exception
   {
       ResponseEntity<?> validate = FormFieldValidator.validate(form);
       if(validate.getStatusCode() != HttpStatus.OK)
           return validate;
       else
       {
           return SignupService.signup(form, appInstances);
       }
   }

   @RequestMapping(method = RequestMethod.GET, value = "/login")
   public ResponseEntity<?> login()
   {
       UserDetails loadUserByUsername = appUserDetails.loadUserByUsername("test");
       logger.info("loadUserByUsername ========= "+loadUserByUsername);
       return new ResponseEntity("Hello",HttpStatus.OK);
   }   
}

此处logger.info永远不会被调用。

这是我的登录表单

        <form id="loginForm" method="post">
            <input type="text" class="form-control" placeholder="your email" name='j_username'>
            <input type="password" size="10" class="form-control" placeholder="password" name='j_password'>
          </div>
          <button type="submit" class="btn btn-primary">Log In</button>
        </form>


        $.ajax({
            url:"${pageContext.servletContext.contextPath}/login",
            type:"POST",
            beforeSend: function( xhr ) {xhr.setRequestHeader($("meta[name='_csrf_header']").attr("content"), $("meta[name='_csrf']").attr("content"));},
            data:{j_username:$("#loginForm :input[name=j_username]").val(),j_password:$("#loginForm :input[name=j_password]").val()}
        }).done(function(d){
            alert("OK : "+d);
        }).error(function(jqXHR, textStatus, errorThrown){
            alert("Error: "+textStatus);
        });

LoggedInUSer.java

public class LoggedInUser extends User{

    private String name;
    private String userId;
    private String userName;

    public String getName() {
        return name;
    }

    public String getUserId() {
        return userId;
    }

    public String getUserName() {
        return userName;
    }

    public boolean isBlock() {
        return block;
    }
    private boolean block;

    public LoggedInUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {         
         super(username, password, enabled, accountNonExpired,credentialsNonExpired, accountNonLocked, authorities);
         //super(username, password, authorities);
         this.name = name;
         this.userId = userId;
         this.userName=userName;
         this.block=block;
    }
}

每当我输入usernametestpassword123我就

Your login attempt was not successful, try again.
Reason: Bad credentials

作为回应。我错过了什么?

这是完整日志

https://drive.google.com/file/d/0B9pquofzd_JYTlVPZ3ZvRF83S1k/view?usp=sharing

1 个答案:

答案 0 :(得分:0)

根据您提供的不完整日志(如Rob担任Spring Security的项目负责人并且本来是地球上最好的人来帮助您的那样),有以下几点:

  1. 您正在使用带有<form-login>的Spring Security 4.0.1:错误凭据是因为SS 4+将查找属性名称为&#39; username&#39; &安培; &#39;密码&#39;但是你提供了&#39; j_username&#39; &安培; &#39;为j_password&#39;代替。仅在那个时候,
  2. 你的logger.info永远不会被调用:正确如此。它没有理由被召唤!首先,无论何时向/ login发出POST请求,它都将与spring安全过滤器链中的默认登录处理URL匹配,并且您将获得错误凭据。其次,它有一个与之关联的请求方法GET,无论何时直接请求,都会出现默认的SS登录页面(因为它是由DefaultLoginPageGeneratingFilter提供的,甚至在你的调度程序发送之前。
  3. 您会收到一个登录表单:这是SS的配置使用登录表单时的预期行为。
  4. 如果您仍需要一些帮助,请提供DEBUG日志(将log4j日志级别设置为DEBUG;从您的记录器调用看起来,您似乎正在使用Log4J)。

相关问题