java - 使用 Spring Security 针对数据库故障进行身份验证。

标签 java spring spring-security

我正在尝试将 Spring Security 添加到我的 Spring Boot 应用程序中。我有具有用户和权限的数据库:

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 的登录并得到:

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

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

最佳答案

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

关于java - 使用 Spring Security 针对数据库故障进行身份验证。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33569874/

相关文章:

带有/j_spring_security_logout 的 Spring-Security 可能没有完全注销

java - 如何解决此 j2ee 架构中的重复属性错误?

java - 如何强制退出Android应用程序并重新启动它?

Spring Security 和 @Async(经过身份验证的用户混在一起)

java - 如何解决Hibernate中的级联删除问题?

java - Hibernate Criteria 集合的最新日期字段

Java - 安全性已开启,但我仍然可以发送我想要的任何请求

java - 使用 netty-socketio 服务器限制 websocket

java - 新用户持有搜索数组

spring - 跨多个 Gradle 项目重用 spring 测试上下文