2015-11-06 84 views
0

我正在尝试为我的春季启动应用添加弹簧安全功能。我有Db用户和权限:使用弹簧安全性对数据库失败进行身份验证。

CREATE TABLE USERS(
    USERNAME TEXT NOT NULL PRIMARY KEY, 
    PASSWORD TEXT NOT NULL, 
    ENABLED BOOLEAN NOT NULL 
); 

CREATE TABLE AUTHORITIES(
    USERNAME TEXT REFERENCES USERS(USERNAME), 
    AUTHORITY TEXT NOT NULL 
); 

INSERT INTO USERS(USERNAME,PASSWORD,ENABLED) 
VALUES ('admin','$2a$10$0eJqlbYcHCD5EyuI0TnuhetVt6p3NDBFXyGtB6D0oigN2mshk2KUu',true); 

INSERT INTO AUTHORITIES(USERNAME, AUTHORITY) VALUES('admin','ROLE_ADMIN'); 

用简单的admin:admin作为凭证。我写了简单的登录页面,没有什么花哨只是引导例如:

<%@ page contentType="text/html;charset=UTF-8" language="java" %> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> 
    <meta name="description" content="login"> 
    <link rel="icon" href="../favicon.ico"> 

    <title>Signin Template for Bootstrap</title> 

    <!-- Bootstrap core CSS --> 
    <link href="css/bootstrap.min.css" rel="stylesheet"> 

    <!-- Custom styles for this template --> 
    <link href="css/signin.css" rel="stylesheet"> 

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> 
    <!--[if lt IE 9]> 
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> 
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> 
    <![endif]--> 
</head> 

<body> 
<div class="container"> 

    <form name="loginForm" class="form-signin" action="j_spring_security_check" method='POST'> 
     <c:if test="${not empty error}"> 
      <div class="alert alert-danger" role="alert"> 
       Invalid username or password! 
      </div> 
     </c:if> 
     <c:if test="${not empty msg}"> 
      <div class="alert alert-success" role="alert"> 
       Logged out successfully! 
      </div> 
     </c:if> 
     <label for="j_username" class="sr-only">Login</label> 
     <input type="text" id="j_username" class="form-control" placeholder="Login" required autofocus> 

     <label for="j_password" class="sr-only">Password</label> 
     <input type="password" id="j_password" class="form-control" placeholder="Password" required> 

     <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> 
    </form> 
</div> <!-- /container --> 
</body> 
</html> 

这是我的配置:

package worker.security; 

import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 
import org.springframework.security.crypto.password.PasswordEncoder; 

import javax.sql.DataSource; 

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    DataSource dataSource; 

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(SecurityConfig.class); 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
       .authorizeRequests() 
       .antMatchers("/", "/js/**", "/css/**", "/api/**") 
       .permitAll() 
       .anyRequest().authenticated() 
       .and() 
       .formLogin() 
       .loginPage("/login") 
       .loginProcessingUrl("/j_spring_security_check") 
       .defaultSuccessUrl("/monitor") 
       .failureUrl("/login?error") 
       .usernameParameter("j_username") 
       .passwordParameter("j_password") 
       .permitAll() 
       .and() 
       .logout() 
       .logoutSuccessUrl("/login?logout") 
       .permitAll() 
       .and() 
       .csrf(). 
       disable(); 
    } 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.jdbcAuthentication().dataSource(dataSource) 
       .passwordEncoder(passwordEncoder()) 
       .usersByUsernameQuery("select username, password, enabled from users where username=?") 
       .authoritiesByUsernameQuery("select username, authority from authorities where username=?"); 
    } 

    @Bean 
    public PasswordEncoder passwordEncoder() { 
     PasswordEncoder encoder = new BCryptPasswordEncoder(); 
     return encoder; 
    } 
} 

每次当我尝试登录我得到登录错误。我尝试将身份验证更改为内存,但没有帮助。我启用了org.spring.security的loggin,并得到:

16:09:34.838 [http-nio-8080-exec-4] DEBUG o.s.s.p.JdbcUserDetailsManager(176) - Query returned no results for user '' 
16:09:34.955 [http-nio-8080-exec-4] DEBUG o.s.s.a.d.DaoAuthenticationProvider(147) - User '' not found 

但是,当从命令行执行时,相同的查询返回所需的行。 somone可以帮忙吗?

+0

您使用的是哪个版本的Spring Security? –

回答

3

OK,我得到了我的答案,你正在使用Spring Security的4 X。但是,在你的JSP,你<input>字段使用id属性,而不是name命名。只需将您的id值复制到name,一切都应该正常工作。不要放弃你的id属性,你仍然需要它们为您<label for="...">标签。

<input type="text" id="j_username" name="j_username" 
    class="form-control" placeholder="Login" required autofocus> 
<input type="password" id="j_password" name="j_password" 
    class="form-control" placeholder="Password" required>