Spring Security 实现基于数据库的用户登录和修改密码

1 pom.xml(Maven依赖文件)

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- Spring Security-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Mysql驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- Mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--hutool工具包-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.5.1</version>
        </dependency>

        <!-- swagger2-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

2 application.properties(配置文件)

设置MySQL连接配置和MyBatis配置。

#数据库连接池设置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root

#mybatis的相关配置
mybatis.mapper-locations=classpath:mapper/*.xml

3 SQL

创建语句:

create table users(
	username varchar(20) PRIMARY key COMMENT '用户名',
	password varchar(60) comment '密码'
)

添加数据语句: 

--密码123456
insert into users(username,password) values('xudongmaster','$2a$10$ky8Gyh5cjVRXnzXE4VO.wuHARs9eAF7VIvSz6R4idnrSnSl4E4pwy');

4 entity(实体类)

User.java:

package com.entity;

import lombok.Data;
import org.springframework.stereotype.Component;

@Component
@Data
public class User {
    /**
     * 用户名(登录)
     */
    private String username;
    /**
     * 密码
     */
    private String password;
}

5 Mapper(映射层)

UserMapper.java:

package com.mapper;

import com.entity.User;
import org.springframework.stereotype.Component;

@Component
public interface UserMapper {
    /**
     * 根据用户名获取用户信息
     *
     * @param username 用户名
     * @return
     */
    User getUserById(String username);

    /**
     * 更新用户密码
     *
     * @param user 用户信息
     */
    void updatePassword(User user);
}

UserMapper.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.mapper.UserMapper">
    <!-- 根据用户名获取用户信息    -->
    <select id="getUserById" resultType="com.entity.User" parameterType="String">
        select username,password
         from users
         where username = #{username}
    </select>
    <!-- 更新用户密码    -->
    <select id="updatePassword" parameterType="com.entity.User">
        update users
         set password = #{password}
         where username = #{username}
    </select>
</mapper>

6 Service(业务层)

UserSevice.java:

package com.service;

import com.entity.User;

public interface UserService {
    /**
     * 更新用户密码
     *
     * @param user 用户信息
     */
    String updatePassword(User user);
}

UserServiceImpl.java: 

package com.service.impl;

import cn.hutool.core.util.StrUtil;
import com.entity.User;
import com.mapper.UserMapper;
import com.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    /**
     * 更新用户密码
     *
     * @param user 用户信息
     */
    @Override
    public String updatePassword(User user) {
        if (user==null||StrUtil.isBlank(user.getUsername()) || StrUtil.isBlank(user.getPassword())) {
            return "用户名或密码为空";
        }
        //加密
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        //更新密码
        userMapper.updatePassword(user);
        return "更新密码成功";
    }
}

LoginService.java: 

package com.service;

import com.entity.User;

public interface LoginService {
    /**
     * 登录
     *
     * @param user 登录信息
     * @return
     */
    String login(User user);
}

LoginServiceImpl.java: 

package com.service.impl;

import cn.hutool.core.util.StrUtil;
import com.entity.User;
import com.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Component;


@Component
public class LoginServiceImpl implements LoginService {
    @Autowired
    private AuthenticationManager authenticationManager;

    /**
     * 登录
     *
     * @param user 登录信息
     * @return
     */
    @Override
    public String login(User user) {
        if (user == null || StrUtil.isBlank(user.getUsername())) {
            return "用户名不能为空!";
        }
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                return "用户名不存在或密码错误";
            } else {
                e.printStackTrace();
                return e.getMessage();
            }
        }
        return "登录成功";
    }
}

 7 Controller(控制层)

UserController.java:

package com.controller;

import com.entity.User;
import com.service.UserService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    /**
     * 更新用户密码
     *
     * @param user 用户信息
     */
    @PostMapping("/updatePassword")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名"),
            @ApiImplicitParam(name = "password", value = "密码")
    })
    public String updatePassword(@RequestBody User user){
        return userService.updatePassword(user);
    }
}

LoginController.java:

package com.controller;

import com.entity.User;
import com.service.LoginService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/")
public class LoginController {
    @Autowired
    LoginService loginService;

    /**
     * 登录
     *
     * @param user 登录信息
     * @return
     */
    @PostMapping("/login")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名"),
            @ApiImplicitParam(name = "password", value = "密码")
    })
    public String login(@RequestBody User user) {
        return loginService.login(user);
    }
}

8 Application(应用启动类)

DemoApplication.java:

package com;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication
@MapperScan("com.mapper")
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

9 Config(配置类)

SecurityConfig.java(Spring Security配置类)。

package com.config;

import com.entity.CustomPasswordEncoder;
import com.service.impl.UserDetailServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.StandardPasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    /**
     * 安全性设置
     *
     * @param httpSecurity
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                // CSRF禁用
                // 从Spring Security 4.0开始,默认情况下会启用CSRF保护,以防止CSRF攻击应用程序,Spring Security CSRF会针对PATCH,POST,PUT和DELETE方法进行防护。
                .csrf().disable()
                // 过滤请求
                .authorizeRequests()
                //允许匿名访问
                .antMatchers("/login","/user/updatePassword").anonymous()
                // 除上面外的所有请求全部需要鉴权认证
                .anyRequest().authenticated();
    }


    /**
     * 身份认证接口
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                // 从数据库读取的用户进行身份认证
                .userDetailsService(userDetailsService)
                //加密方法(强散列哈希加密)
                .passwordEncoder(new BCryptPasswordEncoder());
    }

    /**
     * 解决 无法直接注入 AuthenticationManager
     *
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * 强散列哈希加密实现
     */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

10 UserDetailsService(获取用户信息)

UserDetailServiceImpl.java:

package com.service.impl;

import cn.hutool.core.util.StrUtil;
import com.entity.LoginUser;
import com.entity.User;
import com.mapper.UserMapper;
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.Component;

@Component
public class UserDetailServiceImpl implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if (StrUtil.isBlank(username)) {
            return null;
        }
        User user = userMapper.getUserById(username);
        if(user==null||StrUtil.isBlank(user.getUsername())){
            return null;
        }
        return new LoginUser(username,user.getPassword());
    }
}

11 UserDetails(用户信息类)

LoginUser.java:

package com.entity;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

@AllArgsConstructor
@NoArgsConstructor
public class LoginUser implements UserDetails {
    private String username;
    private String password;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    /**
     * 账号没有过期状态(true账号没有过期,false账号已经过期)
     * @return
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    /**
     * 账号没有锁住状态(true账号没有锁住,false账号锁住)
     * @return
     */
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    /**
     * 密码没有过期状态(true密码没有过期,false密码已经过期)
     * @return
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    /**
     * 启用状态(true启用,false禁用)
     * @return
     */
    @Override
    public boolean isEnabled() {
        return true;
    }
}

12 接口调试

用户登录:

修改密码:

 

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
首先,我们需要在数据库中创建一个用户表,表中包含用户的用户名和密码。然后,我们需要创建一个实体类来映射用户表。在该实体类中,我们需要定义用户名和密码等属性。接着,我们需要创建一个DAO层接口来操作用户数据,例如:查询用户、添加用户、修改用户密码等。 在Spring MVC框架中,我们需要创建一个Controller来处理用户密码修改请求。首先,用户需要登录系统,并进入修改密码页面。在该页面中,用户需要输入当前密码和新密码,并进行确认。在用户提交表单之后,Controller层需要验证用户输入的当前密码是否正确,如果不正确则返回错误信息,如果正确则将新密码更新到数据库中。同时,我们可以使用Spring Security来进行用户身份验证和权限控制,确保只有经过认证的用户才能进行密码修改。 在MyBatis框架中,我们需要创建一个Mapper接口,用于定义修改用户密码的SQL语句。在该Mapper中,我们需要定义一个updatePassword方法,接收用户名和新密码作为参数,并将新密码更新到数据库中。 最后,在Spring框架中,我们需要配置相关的bean,包括数据源、事务管理器、MapperScannerConfigurer等。我们可以使用注解或XML配置来完成这些工作。 综上所述,基于Spring MVC、Spring和MyBatis框架,我们可以轻松地实现修改登录用户密码的功能。这不仅可以提升用户体验,还可以增强系统的安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值