Spring Security--连接数据库

简介: 连接数据库

 书接上一篇,在实际的开发中,我们的账号密码不可能是这样写在配置文件中的,应该是要来自于数据库。

接着上一篇的项目,我们继续,在原有的依赖的基础上新增,mysql驱动依赖和mybatis依赖

<dependencies>

   <dependency>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-starter-security</artifactId>

   </dependency>

   <dependency>

       <groupId>org.mybatis.spring.boot</groupId>

       <artifactId>mybatis-spring-boot-starter</artifactId>

       <version>3.0.2</version>

   </dependency>

   <dependency>

       <groupId>mysql</groupId>

       <artifactId>mysql-connector-java</artifactId>

       <version>5.1.49</version>

   </dependency>

   <dependency>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-starter-web</artifactId>

   </dependency>

</dependencies>


在数据库新建一张用户表

image.gif

我们简单一点,就4个字段

image.gif

添加一条数据,在security中,你的密码默认是加密的,不加密在密码前加(noop)

现在我们要用这个账号密码去登录,我们一步一步来操作一下。

先配置一下数据库配置:

image.gif

然后我们需要一个实体类

image.gif

user实现UserDetails 接口,重写里面的方法

package com.example.demo.model;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
/**
 * 定义用户对象,需要实现UserDetails 接口,对于Spring Security框架而言,所有的用户对象都是一个UserDetails 的实例
 *
 * 根据自己实际情况,实现接口里的方法
 */
public class User implements UserDetails {
    private Integer id;
    private String username;
    private String password;
    private Boolean enabled;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }
    /**
     * 用来放回当前用户的角色/权限信息
     * @return
     */
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }
    /**
     * 获取用户的密码
     * @return
     */
    @Override
    public String getPassword() {
        return password;
    }
    /**
     * 获取用户的用户名
     * @return
     */
    @Override
    public String getUsername() {
        return username;
    }
    /**
     * 账户是否没有过期(true是未过期,false是过期)
     * @return
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    /**
     * 账户是否没有被锁定(true是未被锁定,false是已锁定)
     * @return
     */
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }
    /**
     * 密码是否没有过期
     * 一些公司邮件系统密码要求半年修改一次,不改就无法登录
     * @return
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    /**
     * 账户是否可用
     * @return
     */
    @Override
    public boolean isEnabled() {
        return enabled;
    }
}

image.gif

我们的user对象就已经写好了

接下来写一个userservice,image.gif

同样这个接口也要实现一个UserDetailsService接口

代码如下

package com.example.demo.service;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class UserService implements UserDetailsService {
    /**
     * 根据用户名查询用户对象
     * @param username //用户登录时输入的用户名
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return null;
    }
}

image.gif

然后来一个mapper,

image.gif

将UserMapper 注入到UserService中

package com.example.demo.service;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class UserService implements UserDetailsService {
    @Autowired
    UserMapper userMapper;
    /**
     * 根据用户名查询用户对象
     * @param username //用户登录时输入的用户名
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User u = userMapper.loadUserByUsername(username);
        if (u == null){
            //说明用户名不存在
            throw new UsernameNotFoundException("账号不存在");
        }
        return u;
    }
}

image.gif

UserMapper如下

package com.example.demo.mapper;
import com.example.demo.model.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
    User loadUserByUsername(String username);
}

image.gif

UserMapper.xml如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/schema/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="loadUserByUsername" resultType="com.example.demo.model.User">
        select * from user where username=#{username};
    </select>
</mapper>

image.gif

最后在pom文件的build里加

<build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

image.gif

运行成功

输入账号,密码登录,运行成功。

image.gif

这里报404,是因为没有这个页面。

附带说一下

如果是boot2.x版本,5.x的security会出现一个

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

的错误

这个时候新建两个类就行了

package org.ikun.security_demo;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@Component
public class MyPasswordEncoder implements PasswordEncoder {
    @Override
    public String encode(CharSequence rawPassword) {
        return rawPassword.toString();
    }
    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        return encodedPassword.equals(rawPassword.toString());
    }
}

image.gif

package org.ikun.security_demo;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //设置登录,注销,表单登录不用拦截,其他请求要拦截
        http.authorizeRequests().antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
                .logout().permitAll()
                .and()
                .formLogin();
        //关闭默认的csrf认证
        http.csrf().disable();
    }
    @Override
    public void configure(WebSecurity web) throws Exception {
        //设置静态资源不要拦截
        web.ignoring().antMatchers("/js/**","/css/**","/images/**");
    }
}

image.gif


相关文章
|
1月前
|
SQL Java 关系型数据库
Java连接MySQL数据库环境设置指南
请注意,在实际部署时应该避免将敏感信息(如用户名和密码)硬编码在源码文件里面;应该使用配置文件或者环境变量等更为安全可靠地方式管理这些信息。此外,在处理大量数据时考虑使用PreparedStatement而不是Statement可以提高性能并防止SQL注入攻击;同时也要注意正确处理异常情况,并且确保所有打开过得资源都被正确关闭释放掉以防止内存泄漏等问题发生。
85 13
|
1月前
|
SQL 关系型数据库 MySQL
MySQL数据库连接过多(Too many connections)错误处理策略
综上所述,“Too many connections”错误处理策略涉及从具体参数配置到代码层面再到系统与架构设计全方位考量与改进。每项措施都需根据具体环境进行定制化调整,并且在执行任何变更前建议先行测试评估可能带来影响。
683 11
|
1月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
369 4
|
7月前
|
关系型数据库 MySQL Java
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
|
7月前
|
数据库连接 应用服务中间件 PHP
|
6月前
|
安全 Linux 网络安全
YashanDB数据库服务端SSL连接配置
YashanDB支持通过SSL连接确保数据传输安全,需在服务端生成根证书、服务器证书及DH文件,并将根证书提供给客户端以完成身份验证。服务端配置包括使用OpenSSL工具生成证书、设置SSL参数并重启数据库;客户端则需下载根证书并正确配置环境变量与`yasc_env.ini`文件。注意:启用SSL后,所有客户端必须持有根证书才能连接,且SSL与密码认证独立运行。
|
3月前
|
安全 Java Nacos
0代码改动实现Spring应用数据库帐密自动轮转
Nacos作为国内被广泛使用的配置中心,已经成为应用侧的基础设施产品,近年来安全问题被更多关注,这是中国国内软件行业逐渐迈向成熟的标志,也是必经之路,Nacos提供配置加密存储-运行时轮转的核心安全能力,将在应用安全领域承担更多职责。
|
3月前
|
SQL XML Java
配置Spring框架以连接SQL Server数据库
最后,需要集成Spring配置到应用中,这通常在 `main`方法或者Spring Boot的应用配置类中通过加载XML配置或使用注解来实现。
361 0