文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringSecurity数据库进行认证和授权的使用

2024-04-02 19:55

关注

在前面的文章中,我们介绍了Spring Security基于内存的一些基本使用方法,但在真实的业务场景中,用户的账号、密码以及角色信息肯定都是存放在数据库中的,所以我们需要从数据库中来加载认证和授权的数据。

一、准备工作

如下案例是基于上一篇中的案例改造而来,所以建议先阅读前一篇文章的内容,将基本案例的代码准备好。

1.1 导入相关依赖

除了引入security的依赖外,我们还需要引入数据库驱动、连接池、MyBatis的依赖包:


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

 
<!-- security使用数据库做验证需要增加如下三个依赖 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.6</version>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

1.2 配置信息

我们需要在配置文件中增加数据源的配置信息,指定mapper xml的位置,这里改成你自己的位置即可。


# 配置数据源信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://x.x.x.x:3306/zhangxun?characterEncoding=utf-8&&serverTimezone=Asia/Shanghai&&useSSL=false
spring.datasource.username=root
spring.datasource.password=root

# 配置mapper xml的位置
mybatis.mapper-locations=classpath:mapper
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for(Role role : roles){
            // 也可以在数据中添加角色时,就以 ROLE_ 开始,这样就不用二次添加了
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleCode()));
        }
        return authorities;
    }

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

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


    
    @Override
    public boolean isAccountNonExpired() {
        return (expired == 0);
    }

    
    @Override
    public boolean isAccountNonLocked() {
        return (locked == 0);
    }

    
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    
    @Override
    public boolean isEnabled() {
        return true;
    }
}

实现UserDetails接口的实体类会被认为是User实体,Spring Security会根据重写的方法来加载用户的必要信息:账户信息、密码信息、账户过期、账户锁定、密码过期、账户启用、账户拥有的角色信息。

1.5 Dao层的创建


@Mapper
public interface UserMapper {
    User getUserByUserName(String userName);
    List<Role> getUserRolesByUserId(Integer userId);
}

<?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.securitydemo.mapper.UserMapper">
    <select id="getUserByUserName" parameterType="string" resultType="com.example.securitydemo.po.User">
        select
        au.user_id userId,
        au.user_name userName,
        au.password,
        au.expired,
        au.locked
        from
        auth_user au
        where
        au.user_name = #{userName}
    </select>

    <select id="getUserRolesByUserId" parameterType="integer" resultType="com.example.securitydemo.po.Role">
        select
        ar.role_id roleId,
        ar.role_code roleCode,
        ar.role_name roleName
        from
        auth_user_role aur
        left join auth_role ar on
        aur.role_code = ar.role_code
        where
        aur.user_id = #{userId}
    </select
</mapper>

注意,如果UserMapper接口你是用了@Repository注解,那么就需要在启动类上加上Mapper所在包的位置。


@MapperScan("com.example.securitydemo.mapper")

1.6 Service层的编写


@Slf4j
@Service
public class UserService implements UserDetailsService {

    @Resource
    private UserMapper userMapper;

    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 用户名必须是唯一的,不允许重复
        User user = userMapper.getUserByUserName(username);
        if(ObjectUtils.isEmpty(user)){
            throw new UsernameNotFoundException("根据用户名找不到该用户的信息!");
        }
        List<Role> roleList = userMapper.getUserRolesByUserId(user.getUserId());
        user.setRoles(roleList);
        return user;
    }
}


1.7 Security配置


@EnableWebSecurity
public class DBSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 任何角色允许访问
                .antMatchers("/", "/index").permitAll()
                // 仅admin角色可以访问
                .antMatchers("/admin
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

1.8 密码加密


@Slf4j
public class PasswordEncode {

    private PasswordEncoder passwordEncoder;

    @Before
    public void before(){
        this.passwordEncoder = new BCryptPasswordEncoder();
    }

    @Test
    public void encodePassword(){
        String rawPassword = "mm000";
        String encodePassword = passwordEncoder.encode(rawPassword);
        log.info("password:{} encoded is: {}", rawPassword, encodePassword);
    }

}

该类是一个测试类,为了将明文密码加密后得到密文的,密文存储到User表的password字段。Spring Security默认开启密码加密功能的,数据库加载出来的密码会被进行格式校验,如果不是合法的密文,登录逻辑就会失败。

1.9 测试结果

访问localhost:8080/index无需登录,直接就能返回结果。

访问localhost:8080/admin/getHello将跳转到登录页面,使用root账户(包含admin和manager两个角色),随便输入一个密码,登录失败;输入正确的密码,登录成功后返回正确的内容;此时再访问localhost:8080/manager/getHello也能获得正确的内容。

调用localhost:8080/logout后将退出登录,此时使用zhang账户(仅包含manager角色),输入正确的密码,登录成功后返回正确的内容;此时再访问localhost:8080/admin/getHello将无法获得内容。

到此这篇关于SpringSecurity数据库进行认证和授权的使用的文章就介绍到这了,更多相关SpringSecurity 数据库认证和授权内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯