SpringBoot整合SpringSecurity(通俗易懂) 2

简介: SpringBoot整合SpringSecurity(通俗易懂)

五、密码修改

UserInfoMapper.java类中添加更新用户密码操作:

@Mapper
@Repository
public interface UserMapper {
 ...
 @Update("update user set password = #{newPwd} where username = #{username}")
    int updatePwd(String username, String newPwd);
}
UserInfoService.java类中添加更新密码的操作方法:
@Service
public class UserInfoService { 
    ...
    public int updatePwd(String oldPwd, String newPwd) {
        // 获取当前登录用户信息(注意:没有密码的)
        UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String username = principal.getUsername();
        // 通过用户名获取到用户信息(获取密码)
        UserInfo userInfo = userInfoMapper.getUserInfoByUsername(username);
        // 判断输入的旧密码是正确
        if (passwordEncoder.matches(oldPwd, userInfo.getPassword())) {
            // 不要忘记加密新密码
            return userInfoMapper.updatePwd(username, passwordEncoder.encode(newPwd));
        }
        return 0;
    }
}

HelloController.java类增加修改用户密码接口:

@RestController
public class HelloController {    
    @PutMapping("/updatePwd")
    public int updatePwd(@RequestBody Map<String, String> map){
        return userInfoService.updatePwd(map.get("oldPwd"), map.get("newPwd"));
    }
}

启动程序,因为需要登录,且修改密码请求方式为PUT请求,所以无法使用Postman发起请求,可以使用谷歌浏览器的插件Restlet Client:

先浏览器输入http://localhost:8080/login登录用户zeng/zeng123:

在Restlet Client中进行PUT更新请求:

这里更新后,需要重启后就可以使用新密码登录了。

5.用户角色多对多关系

上面的设置后,能基本实现了身份认证和角色授权了,但还是有一点不足:


我们前面用户表中,用户和角色是绑定一起,用户就只有一个角色了,但实际上,用户可能拥有多个角色,角色拥有多个用户,是多对多的关系,所以需要重新设置用户表和角色表。

创建普通项目运行

IDEA创建一个 Spring Initializr模块项目,名为b-database-manytomany-role,选择Spring Security和web依赖,其他按需选择Lombok、MySQL、JDBC和MyBatis。


先按照普通项目创建起来正常访问,在pom.xml中,先把Spring Security依赖注释

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

新建表,主键id全部都是自增。


用户user2表


CREATE TABLE user2 ( uid int(11) NOT NULL AUTO_INCREMENT,

username varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci

NULL DEFAULT NULL, password varchar(255) CHARACTER SET utf8

COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (uid) USING

BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8

COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;


角色role2表,指定了2个角色


CREATE TABLE role2 ( rid int(11) NOT NULL AUTO_INCREMENT,

role varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL

DEFAULT NULL, PRIMARY KEY (rid) USING BTREE ) ENGINE = InnoDB

AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci

ROW_FORMAT = Dynamic;


用户角色关系user2_role2表


CREATE TABLE user2_role2 ( id int(11) NOT NULL AUTO_INCREMENT,

uid int(11) NULL DEFAULT NULL, rid int(11) NULL DEFAULT NULL,

PRIMARY KEY (id) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 10

CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;


初始化数据:


– 添加1个用户 INSERT INTO user2 VALUES (1, ‘user’, ‘user123’);


– 添加2个角色 INSERT INTO role2 VALUES (1, ‘user’); INSERT INTO role2 VALUES (2, ‘admin’);


– 1个用户,拥有2个角色 INSERT INTO user2_role2 VALUES (1, 1, 1); INSERT INTO user2_role2 VALUES (2, 1, 2);

使用Navicat可视化表的数据结构为:

创建entity实体类

User类

@Data
public class User {
    private Integer uid;
    private String username;
    private String password;
}

Role类

@Data
public class Role {
    private Integer rid;
    private String role;
}

创建DTO类


因为用户和角色是多对多关系,需要在用户中含有角色的对象,角色中含有用户的对象,创建DTO类而不再entity类中添加,是因为entity类属性是和表字段一一对应的,一般不推荐在entity类中添加与表字段无关的属性。


新建dto包,在包下创建如下类:


UserDTO类


// 注意,多对多不要用@Data,因为ToString会相互调用,导致死循环

@Setter
@Getter
public class UserDTO extends User {
    private Set<Role> roles;
}

RoleDTO类(目前用不到,可不建)

// 注意,多对多不要用@Data,因为ToString会相互调用,导致死循环

@Setter
@Getter
public class RoleDTO extends Role {
    private Set<User> users;
}

添加UserMapper.java类

@Mapper
@Repository
public interface UserMapper {
    // 查询用户
    UserDTO selectUserByUsername(@Param("username") String username);
}

UserMapper.xml。因为需要关联查询,所有使用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.example.bdatabasemanytomanyrole.mapper.UserMapper">
    <resultMap id="userRoleMap" type="com.example.bdatabasemanytomanyrole.dto.UserDTO">
        <id property="uid" column="uid"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <collection property="roles" ofType="com.example.bdatabasemanytomanyrole.dto.RoleDTO">
            <id property="rid" column="rid"/>
            <result property="role" column="role"></result>
        </collection>
    </resultMap>
    <select id="selectUserByUsername" resultMap="userRoleMap">
        select user2.uid, user2.username, user2.password, role2.rid, role2.role
        from user2, user2_role2, role2
        where user2.username=#{username} 
        and user2.uid = user2_role2.uid 
        and user2_role2.rid = role2.rid
    </select>
</mapper>

UserService.java

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public UserDTO getUser(String username){
        return userMapper.selectUserByUsername(username);
    }
}

UserController.java

@RestController
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/get-user")
    public UserDTO getUser(@RequestParam String username){
        return userService.getUser(username);
    }
}

上面完成后,启动项目,访问localhost:8080/get-user?username=user,查询到的用户信息为:

引入Spring Security安全验证

把pom.xml中的Spring Security依赖注释去掉:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

此时,再重新启动程序,访问localhost:8080/get-user?username=user时,会跳转到登录页面。此时默认的登录用户名为user,密码在启动时打印在控制台。


从数据库中获取用户、密码进行登录:


添加MyUserDetailsService.java,实现UserDetailsService,重写loadUserByUsername方法:

@Component
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserService userService;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDTO user = userService.getUser(username);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        // 添加用户拥有的多个角色
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        Set<Role> roles = user.getRoles();
        for (Role role : roles) {
            grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRole()));
        }
        return new User(
                user.getUsername(),
             // 数据库中密码没加密,需加密
                new BCryptPasswordEncoder().encode(user.getPassword()),
                grantedAuthorities
        );
    }
}

添加WebSecurityConfig.java,继承WebSecurityConfigurerAdapter,重写configure(AuthenticationManagerBuilder auth)方法:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyUserDetailsService userDetailsService;
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
 }        
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDatailService)
                .passwordEncoder(passwordEncoder());
    }
}

重新启动,可以使用user/user123登录了。

查看登录用户信息

要查看登录用户信息,我们可以在UserController中添加方法:

@RestController
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/get-user")
    public UserDTO getUser(@RequestParam String username){
        return userService.getUser(username);
    }
    /**
     * 查看登录用户信息
     */
    @GetMapping("/get-auth")
    public Authentication getAuth(){
        return SecurityContextHolder.getContext().getAuthentication();
    }
}

重新启动登录后,访问localhost:8080/get-auth,返回:

以上就是本篇文章的有关内容

骚等别划走,恰饭时间~

目录
相关文章
|
3月前
|
存储 安全 Java
SpringBoot搭建Spring Security 入门
SpringBoot搭建Spring Security 入门
114 0
|
2月前
|
存储 安全 Java
Spring Boot整合Spring Security--学习笔记
Spring Boot整合Spring Security--学习笔记
55 1
|
3月前
|
前端开发 安全 Java
SpringBoot 实现登录验证码(附集成SpringSecurity)
SpringBoot 实现登录验证码(附集成SpringSecurity)
|
22天前
|
安全 数据安全/隐私保护
Springboot+Spring security +jwt认证+动态授权
Springboot+Spring security +jwt认证+动态授权
|
6月前
|
安全 前端开发 Java
微服务技术系列教程(38)- SpringBoot -整合SpringSecurity
微服务技术系列教程(38)- SpringBoot -整合SpringSecurity
60 0
|
3月前
|
前端开发 JavaScript Java
基于Springboot+SpringSecurity+Activiti7实现的工作流系统可方便二次开发(附完整源码)
基于Springboot+SpringSecurity+Activiti7实现的工作流系统可方便二次开发(附完整源码)
59 0
|
4月前
|
安全 Java Spring
springboot整合spring security 实现用户登录注册与鉴权全记录
【1月更文挑战第11天】springboot整合spring security 实现用户登录注册与鉴权全记录
97 2
|
4月前
|
安全 Java Spring
springboot整合spring security 安全认证框架
springboot整合spring security 安全认证框架
|
5月前
|
安全 Java 数据安全/隐私保护
Spring Security在Spring Boot中的讲解与实战(附源码)
Spring Security在Spring Boot中的讲解与实战(附源码)
49 0
|
5月前
|
安全 Java 数据库
SpringBoot - 安全入门与SpringSecurity
SpringBoot - 安全入门与SpringSecurity
38 0