最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringSecurity數(shù)據(jù)庫(kù)進(jìn)行認(rèn)證和授權(quán)的使用

 更新時(shí)間:2021年08月18日 10:08:33   作者:文景大大  
本文主要介紹了用戶(hù)的賬號(hào)、密碼以及角色信息在數(shù)據(jù)庫(kù)中的認(rèn)證和授權(quán),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前面的文章中,我們介紹了Spring Security基于內(nèi)存的一些基本使用方法,但在真實(shí)的業(yè)務(wù)場(chǎng)景中,用戶(hù)的賬號(hào)、密碼以及角色信息肯定都是存放在數(shù)據(jù)庫(kù)中的,所以我們需要從數(shù)據(jù)庫(kù)中來(lái)加載認(rèn)證和授權(quán)的數(shù)據(jù)。

一、準(zhǔn)備工作

如下案例是基于上一篇中的案例改造而來(lái),所以建議先閱讀前一篇文章的內(nèi)容,將基本案例的代碼準(zhǔn)備好。

1.1 導(dǎo)入相關(guān)依賴(lài)

除了引入security的依賴(lài)外,我們還需要引入數(shù)據(jù)庫(kù)驅(qū)動(dòng)、連接池、MyBatis的依賴(lài)包:

<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使用數(shù)據(jù)庫(kù)做驗(yàn)證需要增加如下三個(gè)依賴(lài) -->
<!-- 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 配置信息

我們需要在配置文件中增加數(shù)據(jù)源的配置信息,指定mapper xml的位置,這里改成你自己的位置即可。

# 配置數(shù)據(jù)源信息
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/*Mapper.xml

# 是否顯示執(zhí)行sql
logging.level.com.xun.mapper=debug

1.3 數(shù)據(jù)庫(kù)準(zhǔn)備

我們需要?jiǎng)?chuàng)建如下三張表,分別用來(lái)存儲(chǔ)用戶(hù)信息、角色信息、用戶(hù)與角色的對(duì)應(yīng)關(guān)系。

CREATE TABLE `auth_user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(100) DEFAULT NULL,
  `password` varchar(100) DEFAULT NULL,
  `expired` tinyint(1) DEFAULT NULL,
  `locked` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4

-- 密文密碼的生成邏輯下面1.8節(jié)會(huì)講到,可以替換為自己密碼的密文進(jìn)行插入
INSERT INTO zhangxun.auth_user (user_id, user_name, password, expired, locked) VALUES(1, 'root', '$2a$10$Hv037iGDdj82YjFORlYnyOdlra2EObV2XdddyW8A.r.Ph5ETOBNo2', 0, 0);
INSERT INTO zhangxun.auth_user (user_id, user_name, password, expired, locked) VALUES(2, 'zhang', '$2a$10$cVgFLGx0Crz0Jf2TDBhJ.e6FS.BpH7YOoox2iSJrGW1DJ6OXiOt86', 0, 0);
CREATE TABLE `auth_role` (
  `role_id` int(11) NOT NULL AUTO_INCREMENT,
  `role_code` varchar(100) DEFAULT NULL,
  `role_name` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

INSERT INTO zhangxun.auth_role (role_id, role_code, role_name) VALUES(1, 'admin', '管理員');
INSERT INTO zhangxun.auth_role (role_id, role_code, role_name) VALUES(2, 'manager', '經(jīng)理');
CREATE TABLE `auth_user_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `role_code` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

-- root用戶(hù)將擁有admin和manager兩個(gè)角色,zhang用戶(hù)僅擁有manager一個(gè)角色
INSERT INTO zhangxun.auth_user_role (id, user_id, role_code) VALUES(1, 1, 'admin');
INSERT INTO zhangxun.auth_user_role (id, user_id, role_code) VALUES(2, 1, 'manager');
INSERT INTO zhangxun.auth_user_role (id, user_id, role_code) VALUES(3, 2, 'manager');

1.4 實(shí)體類(lèi)的創(chuàng)建

@Data
public class Role {
    private Integer roleId;
    private String roleCode;
    private String roleName;
}
@Data
public class User implements UserDetails {
    private Integer userId;
    private String userName;
    private String password;
    private Integer expired;
    private Integer locked;
    private List<Role> roles;

    /**
     * 獲取用戶(hù)的所有角色信息
     * @return
     */
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for(Role role : roles){
            // 也可以在數(shù)據(jù)中添加角色時(shí),就以 ROLE_ 開(kāi)始,這樣就不用二次添加了
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleCode()));
        }
        return authorities;
    }

    /**
     * 指定哪一個(gè)是用戶(hù)的密碼字段
     * @return
     */
    @Override
    public String getPassword() {
        return password;
    }

    /**
     * 指定哪一個(gè)是用戶(hù)的賬戶(hù)字段
     * @return
     */
    @Override
    public String getUsername() {
        return userName;
    }


    /**
     * 判斷賬戶(hù)是否過(guò)期
     * @return
     */
    @Override
    public boolean isAccountNonExpired() {
        return (expired == 0);
    }

    /**
     * 判斷賬戶(hù)是否鎖定
     * @return
     */
    @Override
    public boolean isAccountNonLocked() {
        return (locked == 0);
    }

    /**
     * 判斷密碼是否過(guò)期
     * 可以根據(jù)業(yè)務(wù)邏輯或者數(shù)據(jù)庫(kù)字段來(lái)決定
     * @return
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    /**
     * 判斷賬戶(hù)是否可用
     * 可以根據(jù)業(yè)務(wù)邏輯或者數(shù)據(jù)庫(kù)字段來(lái)決定
     * @return
     */
    @Override
    public boolean isEnabled() {
        return true;
    }
}

實(shí)現(xiàn)UserDetails接口的實(shí)體類(lèi)會(huì)被認(rèn)為是User實(shí)體,Spring Security會(huì)根據(jù)重寫(xiě)的方法來(lái)加載用戶(hù)的必要信息:賬戶(hù)信息、密碼信息、賬戶(hù)過(guò)期、賬戶(hù)鎖定、密碼過(guò)期、賬戶(hù)啟用、賬戶(hù)擁有的角色信息。

1.5 Dao層的創(chuàng)建

@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注解,那么就需要在啟動(dòng)類(lèi)上加上Mapper所在包的位置。

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

1.6 Service層的編寫(xiě)

@Slf4j
@Service
public class UserService implements UserDetailsService {

    @Resource
    private UserMapper userMapper;

    /**
     * 根據(jù)用戶(hù)名去數(shù)據(jù)庫(kù)獲取用戶(hù)信息,SpringSecutity會(huì)自動(dòng)進(jìn)行密碼的比對(duì)
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 用戶(hù)名必須是唯一的,不允許重復(fù)
        User user = userMapper.getUserByUserName(username);
        if(ObjectUtils.isEmpty(user)){
            throw new UsernameNotFoundException("根據(jù)用戶(hù)名找不到該用戶(hù)的信息!");
        }
        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;

    /**
     * 對(duì)請(qǐng)求進(jìn)行鑒權(quán)的配置
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 任何角色允許訪問(wèn)
                .antMatchers("/", "/index").permitAll()
                // 僅admin角色可以訪問(wèn)
                .antMatchers("/admin/**").hasRole("admin")
                // admin和manager兩個(gè)角色可以訪問(wèn)
                .antMatchers("/manager/**").hasAnyRole("admin", "manager")
                .and()
                // 沒(méi)有權(quán)限進(jìn)入內(nèi)置的登錄頁(yè)面
                .formLogin()
                .and()
                // 暫時(shí)關(guān)閉CSRF校驗(yàn),允許get請(qǐng)求登出
                .csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
    }

    /**
     * 默認(rèn)開(kāi)啟密碼加密,前端傳入的密碼Security會(huì)在加密后和數(shù)據(jù)庫(kù)中的密文進(jìn)行比對(duì),一致的話就登錄成功
     * 所以必須提供一個(gè)加密對(duì)象,供security加密前端明文密碼使用
     * @return
     */
    @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);
    }

}

該類(lèi)是一個(gè)測(cè)試類(lèi),為了將明文密碼加密后得到密文的,密文存儲(chǔ)到User表的password字段。Spring Security默認(rèn)開(kāi)啟密碼加密功能的,數(shù)據(jù)庫(kù)加載出來(lái)的密碼會(huì)被進(jìn)行格式校驗(yàn),如果不是合法的密文,登錄邏輯就會(huì)失敗。

1.9 測(cè)試結(jié)果

訪問(wèn)localhost:8080/index無(wú)需登錄,直接就能返回結(jié)果。

訪問(wèn)localhost:8080/admin/getHello將跳轉(zhuǎn)到登錄頁(yè)面,使用root賬戶(hù)(包含admin和manager兩個(gè)角色),隨便輸入一個(gè)密碼,登錄失??;輸入正確的密碼,登錄成功后返回正確的內(nèi)容;此時(shí)再訪問(wèn)localhost:8080/manager/getHello也能獲得正確的內(nèi)容。

調(diào)用localhost:8080/logout后將退出登錄,此時(shí)使用zhang賬戶(hù)(僅包含manager角色),輸入正確的密碼,登錄成功后返回正確的內(nèi)容;此時(shí)再訪問(wèn)localhost:8080/admin/getHello將無(wú)法獲得內(nèi)容。

到此這篇關(guān)于SpringSecurity數(shù)據(jù)庫(kù)進(jìn)行認(rèn)證和授權(quán)的使用的文章就介紹到這了,更多相關(guān)SpringSecurity 數(shù)據(jù)庫(kù)認(rèn)證和授權(quán)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java equals 方法與hashcode 方法的深入解析

    Java equals 方法與hashcode 方法的深入解析

    面試時(shí)經(jīng)常會(huì)問(wèn)起字符串比較相關(guān)的問(wèn)題,比如:字符串比較時(shí)用的什么方法,內(nèi)部實(shí)現(xiàn)如何?hashcode的作用,以及重寫(xiě)equal方法,為什么要重寫(xiě)hashcode方法?以下就為大家解答,需要的朋友可以參考下
    2013-07-07
  • Spring Boot文件上傳最新解決方案

    Spring Boot文件上傳最新解決方案

    本文給大家分享Spring Boot文件上傳功能的示例代碼,包括單文件上傳示例和多文件上傳,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-07-07
  • Springboot創(chuàng)建項(xiàng)目的圖文教程(idea版本)

    Springboot創(chuàng)建項(xiàng)目的圖文教程(idea版本)

    這篇文章主要介紹了Springboot創(chuàng)建項(xiàng)目的圖文教程(idea版本),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Springboot打包為Docker鏡像并部署的實(shí)現(xiàn)

    Springboot打包為Docker鏡像并部署的實(shí)現(xiàn)

    這篇文章主要介紹了Springboot打包為Docker鏡像并部署的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Spring Boot整合Redis的完整步驟

    Spring Boot整合Redis的完整步驟

    這篇文章主要給大家介紹了關(guān)于Spring Boot整合Redis的完整步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • SpringBoot使用@Autowired為多實(shí)現(xiàn)的接口注入依賴(lài)

    SpringBoot使用@Autowired為多實(shí)現(xiàn)的接口注入依賴(lài)

    這篇文章主要介紹了SpringBoot使用@Autowired為多實(shí)現(xiàn)的接口注入依賴(lài),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java行為型設(shè)計(jì)模式之策略模式詳解

    Java行為型設(shè)計(jì)模式之策略模式詳解

    策略模式屬于Java-設(shè)計(jì)模式中行為模式之一,該模式定義了一系列算法,并將每個(gè)算法封裝起來(lái),使它們可以相互替換。本文將通過(guò)示例詳細(xì)講解這一模式,需要的可以參考一下
    2022-11-11
  • 詳解HandlerInterceptor處理器攔截器的用法

    詳解HandlerInterceptor處理器攔截器的用法

    這篇文章主要介紹了HandlerInterceptor處理器攔截器的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • SpringMVC表單標(biāo)簽使用詳解

    SpringMVC表單標(biāo)簽使用詳解

    這篇文章主要為大家詳細(xì)介紹了SpringMVC表單標(biāo)簽的使用方法,教大家如何用Spring封裝的一系列表單標(biāo)簽
    2017-03-03
  • Java實(shí)現(xiàn)批量下載選中文件功能

    Java實(shí)現(xiàn)批量下載選中文件功能

    這篇文章主要介紹了Java實(shí)現(xiàn)批量下載選中文件功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-11-11

最新評(píng)論

监利县| 中牟县| 时尚| 阿坝县| 莎车县| 平定县| 高要市| 夏邑县| 阿合奇县| 澄迈县| 改则县| 台湾省| 广饶县| 龙南县| 鹰潭市| 新田县| 易门县| 锦屏县| 璧山县| 河池市| 安陆市| 平乡县| 若羌县| 廉江市| 温泉县| 合山市| 林口县| 石嘴山市| 花莲县| 海南省| 信丰县| 宝鸡市| 菏泽市| 大洼县| 广德县| 湘潭县| 当涂县| 兴宁市| 迁西县| 和平区| 商城县|