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


相关文章
|
2天前
|
安全 Java 数据库连接
Spring Boot + Security + MyBatis + Thymeleaf + Activiti 快速开发平台项目
Spring Boot + Security + MyBatis + Thymeleaf + Activiti 快速开发平台项目
12 0
|
3天前
|
安全 Java 测试技术
Spring Security应用中的部分代码示例2
【6月更文挑战第12天】Spring Security应用中的部分代码示例2
13 5
|
3天前
|
安全 Java 数据库
Spring Security应用代码示例
【6月更文挑战第12天】Spring Security应用代码示例
14 3
|
4天前
|
NoSQL 关系型数据库 Serverless
Serverless 应用引擎产品使用合集之连接RDS、Redis等数据库时,是否需要通过安全组来控制访问权限
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
4天前
|
SQL 运维 DataWorks
DataWorks操作报错合集之通过公网连接数据库时,报错连接不稳定,如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
4天前
|
DataWorks 关系型数据库 MySQL
DataWorks操作报错合集之在尝试连接到MySQL数据库时遇到了“Communications link failure”错误,如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
5天前
|
SQL Java 数据库
Java一分钟之-Spring Data JPA:简化数据库访问
【6月更文挑战第10天】Spring Data JPA是Spring Data项目的一部分,简化了Java数据库访问。它基于JPA,提供Repository接口,使开发者能通过方法命名约定自动执行SQL,减少代码量。快速上手包括添加相关依赖,配置数据库连接,并定义实体与Repository接口。常见问题涉及主键生成策略、查询方法命名和事务管理。示例展示了分页查询的使用。掌握Spring Data JPA能提升开发效率和代码质量。
25 0
|
8天前
|
Java 关系型数据库 MySQL
使用CAS登录模块连接数据库验证用户合法性
使用CAS登录模块连接数据库验证用户合法性
8 0
|
8天前
|
JSON 安全 Java
Java一分钟之-Spring Security:身份验证与授权
【6月更文挑战第7天】本文介绍了Spring Security的常见问题及解决方案,包括配置启动、身份验证、授权、无状态JWT和异常处理。通过`@EnableWebSecurity`启动安全框架,自定义登录页面和登录逻辑,使用`http.authorizeRequests()`设置访问规则。对于JWT,需添加解析器并注册过滤器。此外,处理Spring Security异常,创建自定义的`AccessDeniedHandler`和`AuthenticationEntryPoint`。理解核心概念并按业务需求定制,是确保应用安全的关键。
20 1
|
8天前
|
关系型数据库 数据库连接 分布式数据库
PolarDB操作报错合集之数据库访问量低时,可以正常连接数据库,访问量高了所有用户都连接不了数据库,为什么
PolarDB是阿里云推出的一种云原生数据库服务,专为云设计,提供兼容MySQL、PostgreSQL的高性能、低成本、弹性可扩展的数据库解决方案,可以有效地管理和优化PolarDB实例,确保数据库服务的稳定、高效运行。以下是使用PolarDB产品的一些建议和最佳实践合集。