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


目录
打赏
0
0
0
0
26
分享
相关文章
什么是JWT?如何使用Spring Boot Security实现它?
什么是JWT?如何使用Spring Boot Security实现它?
1262 5
【瑶池数据库训练营及解决方案本周精选(探索PolarDB,参与RDS迁移、连接训练营)】(5.30-6.8)
本周精选聚焦数据库迁移训练营、快速连接云数据库RDS训练营及智能多模态搜索解决方案。为用户提供模拟教程与实战演练,学习RDS MySQL实例连接与数据管理技能,助力企业智能化发展。每周解锁数据库实战新场景,抓紧时间,精彩不容错过!
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
YashanDB数据库服务端SSL连接配置
YashanDB支持通过SSL连接确保数据传输安全,需在服务端生成根证书、服务器证书及DH文件,并将根证书提供给客户端以完成身份验证。服务端配置包括使用OpenSSL工具生成证书、设置SSL参数并重启数据库;客户端则需下载根证书并正确配置环境变量与`yasc_env.ini`文件。注意:启用SSL后,所有客户端必须持有根证书才能连接,且SSL与密码认证独立运行。
【Oracle】使用Navicat Premium连接Oracle数据库两种方法
以上就是两种使用Navicat Premium连接Oracle数据库的方法介绍,希望对你有所帮助!
629 28
在C++的QT框架中实现SQLite数据库的连接与操作
以上就是在C++的QT框架中实现SQLite数据库的连接与操作的基本步骤。这些步骤包括创建数据库连接、执行SQL命令、处理查询结果和关闭数据库连接。在实际使用中,你可能需要根据具体的需求来修改这些代码。
206 14
【YashanDB知识库】YDC连接数据库报错yasdb return code is zero
【YashanDB知识库】YDC连接数据库报错yasdb return code is zero
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
250 25

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问