使用spring安全性对db故障进行身份验证

时间:2015-11-06 15:13:50

标签: java spring spring-security

我正在尝试为我的春季启动应用添加Spring安全性。我有用户和权限的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作为凭据。我写了简单的登录页面,没有什么花哨的只是Bootstrap例子:

<%@ 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

但是,从命令行执行时,相同的查询将返回所需的行。 可以提供帮助吗?

1 个答案:

答案 0 :(得分:3)

好的,我得到了答案,您使用的是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>