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

Spring?Security實(shí)現(xiàn)用戶名密碼登錄詳解

 更新時(shí)間:2022年10月25日 08:30:28   作者:Grey  
這篇文章主要為大家詳細(xì)介紹了Spring Security如何實(shí)現(xiàn)用戶名密碼登錄功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下

環(huán)境

JDK 1.8

Spring Boot 2.3.0.RELEASE

Maven 3.6.1

H2 數(shù)據(jù)庫

用戶名密碼登錄

首先,我們用 Spring Security 實(shí)現(xiàn)用戶輸入用戶名密碼登錄驗(yàn)證并獲取相應(yīng)權(quán)限。

E-R圖

完整建表語句

因?yàn)槭菧y(cè)試程序,所以用H2數(shù)據(jù)庫來測(cè)試。SQL腳本在resouces/db目錄下,項(xiàng)目啟動(dòng)后會(huì)自動(dòng)初始化腳本,無需手動(dòng)執(zhí)行。

schema.sql

DROP TABLE IF EXISTS `SYS_ROLE`;
DROP TABLE IF EXISTS `SYS_USER_ROLE`;
DROP TABLE IF EXISTS `SYS_USER`;

create table SYS_ROLE
(
    ID   INT not null primary key,
    NAME VARCHAR(255) not null
);

create table SYS_USER
(
    ID       INT not null primary key,
    NAME     VARCHAR not null,
    PASSWORD VARCHAR(255) not null
);

create table SYS_USER_ROLE
(
    USER_ID INT not null,
    ROLE_ID INT not null,
    constraint pk_1 primary key (ROLE_ID, USER_ID),
    constraint fk_1 foreign key (ROLE_ID) references SYS_ROLE (ID) on update cascade on delete cascade,
    constraint fk_2 foreign key (USER_ID) references SYS_USER (ID) on update cascade on delete cascade
);

data.sql

INSERT INTO `SYS_ROLE` (`ID`, `NAME`) VALUES (1, 'ADMIN'),(2, 'USER');
INSERT INTO `SYS_USER` (`ID`, `NAME`, `PASSWORD`) VALUES (1, 'super', '888888'), (2, 'jack', '666666'), (3, 'lucy', '999999');
INSERT INTO `SYS_USER_ROLE` (`USER_ID`, `ROLE_ID`) VALUES (1, 1),(2, 2),(3, 2);

準(zhǔn)備好建表語句后,完成實(shí)體類的編寫

SysRole.java

package org.hui.login.model;

/**
 * 用戶角色
 * @author zenghui
 * @date 2020-05-20
 */
public class SysRole {
    private Integer id;
    private String name;
  
    public Integer getId() {return id;}
    public void setId(Integer id) {this.id = id;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
}

SysUser.java

package org.hui.login.model;

/**
 * 用戶基本信息
 * @author zenghui
 * @date 2020-05-20
 */
public class SysUser  {
    private Integer id;
    private String name;
    private String password;

    public Integer getId() {return id;}
    public void setId(Integer id) {this.id = id;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public String getPassword() {return password;}
    public void setPassword(String password) {this.password = password;}
}

SysUserRole.java

package org.hui.login.model;

/**
 * 角色和用戶對(duì)應(yīng)關(guān)系
 * @author zenghui
 * @date 2020-05-20
 */
public class SysUserRole  {
    private Integer userId;
    private Integer roleId;

    public Integer getUserId() {return userId;}
    public void setUserId(Integer userId) {this.userId = userId;}
    public Integer getRoleId() {return roleId;}
    public void setRoleId(Integer roleId) {this.roleId = roleId;}
}

以上,完成了數(shù)據(jù)層的設(shè)計(jì)。

POM依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.3.0.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
 </parent>
 <groupId>example</groupId>
 <artifactId>spring-login</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>spring-login</name>
 <description>Spring Security to implements Login</description>

 <properties>
  <java.version>1.8</java.version>
 </properties>
 <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>2.1.2</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <scope>runtime</scope>
  </dependency>
 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>

</project>

配置文件

application.properties

spring.datasource.url=jdbc:h2:mem:userdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=123
#設(shè)置SQL腳本的位置,resources/db目錄下,如果不設(shè)置的話,默認(rèn)就在resources目錄下
spring.datasource.schema=classpath:db/schema.sql
spring.datasource.data=classpath:db/data.sql
#H2控制臺(tái)啟用
spring.h2.console.enabled=true
#訪問H2的URL
spring.h2.console.path=/h2

# 下劃線轉(zhuǎn)化為駝峰命名
mybatis.configuration.map-underscore-to-camel-case=true

Mapper

采用了Mybatis來操作數(shù)據(jù)庫。

準(zhǔn)備好需要的幾個(gè)Mapper,如下

SysRoleMapper.java

package org.hui.login.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.hui.login.model.SysRole;
/**
 * @author zenghui
 * @date 2020-05-20
 */
@Mapper
public interface SysRoleMapper {
    @Select("SELECT * FROM sys_role WHERE id = #{id}")
    SysRole selectById(Integer id);
}

SysUserMapper.java

package org.hui.login.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.hui.login.model.SysUser;
/**
 * @author zenghui
 * @date 2020-05-20
 */
@Mapper
public interface SysUserMapper {
    @Select("SELECT * FROM sys_user WHERE name = #{name}")
    SysUser selectByName(String name);
}

SysUserRoleMapper.java

package org.hui.login.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.hui.login.model.SysUserRole;

import java.util.List;
/**
 * @author zenghui
 * @date 2020-05-20
 */
@Mapper
public interface SysUserRoleMapper {
    @Select("SELECT * FROM sys_user_role WHERE user_id = #{userId}")
    List<SysUserRole> listByUserId(Integer userId);
}

Service設(shè)計(jì)

Spring Security提供了一個(gè)UserDetailsService接口,我們需要實(shí)現(xiàn)這個(gè)接口的loadUserByUsername方法,用于用戶信息的獲取,如果存在用戶,則把用戶的密碼獲取出來,如果不存在這個(gè)用戶,直接拋異常。

我們新建一個(gè)SysUserDetailService.java

package org.hui.login.service;

import org.hui.login.mapper.SysRoleMapper;
import org.hui.login.mapper.SysUserMapper;
import org.hui.login.mapper.SysUserRoleMapper;
import org.hui.login.model.SysRole;
import org.hui.login.model.SysUser;
import org.hui.login.model.SysUserRole;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
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;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author zenghui
 * @date 2020-05-20
 */
@Service
public class SysUserDetailService implements UserDetailsService {
    private final SysUserMapper sysUserMapper;
    private final SysRoleMapper sysRoleMapper;
    private final SysUserRoleMapper sysUserRoleMapper;
    public SysUserDetailService(SysUserMapper sysUserMapper, SysRoleMapper sysRoleMapper, SysUserRoleMapper sysUserRoleMapper) {
        this.sysUserMapper = sysUserMapper;
        this.sysRoleMapper = sysRoleMapper;
        this.sysUserRoleMapper = sysUserRoleMapper;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        Collection<GrantedAuthority> authorities = new ArrayList<>();
        // 從數(shù)據(jù)庫中取出用戶信息
        SysUser user = sysUserMapper.selectByName(username);

        // 判斷用戶是否存在
        if(user == null) {
            throw new UsernameNotFoundException("用戶名不存在");
        }

        // 添加權(quán)限
        List<SysUserRole> userRoles = sysUserRoleMapper.listByUserId(user.getId());
        for (SysUserRole userRole : userRoles) {
            SysRole role = sysRoleMapper.selectById(userRole.getRoleId());
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }

        // 返回UserDetails實(shí)現(xiàn)類
        return new User(user.getName(), user.getPassword(), authorities);

    }
}

如果用戶存在,則會(huì)進(jìn)行密碼的校驗(yàn),方便起見,密碼我們假設(shè)儲(chǔ)存為明文,實(shí)際上密碼有很多加密的策略,這個(gè)后序可以自己配置,密碼校驗(yàn)在SecurityConfig這個(gè)類中,代碼如下:

package org.hui.login.config;

import org.hui.login.service.SysUserDetailService;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author zenghui
 * @date 2020-05-20
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final SysUserDetailService sysUserDetailService;

    public SecurityConfig(SysUserDetailService sysUserDetailService) {
        this.sysUserDetailService = sysUserDetailService;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(sysUserDetailService).passwordEncoder(new PasswordEncoder() {
            @Override
            public String encode(CharSequence charSequence) {
                return charSequence.toString();
            }
            @Override
            public boolean matches(CharSequence charSequence, String s) {
                return s.equals(charSequence.toString());
            }
        });
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
                .and().formLogin().loginPage("/login").defaultSuccessUrl("/").permitAll()
                .and().logout().permitAll();

        // 關(guān)閉CSRF跨域
        http.csrf().disable();
    }

    @Override
    public void configure(WebSecurity web)  {
        web.ignoring().antMatchers("/css/**", "/js/**");
    }
}

以上便完成了所有后端代碼的編寫,接下來,完成controller和前端頁面的編寫。

HTML

在resources的static目錄下,新建兩個(gè)html文件

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄頁</title>
</head>
<body>
<form action="/login" method="post">
    用戶名:<input type="text" name="username">
    密碼:<input type="password" name="password">
    <button type="submit">登錄</button>
</form>
</body>
</html>

home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主頁</title>
</head>
<body>
  登錄成功
</body>
</html>

Controller

新建一個(gè)LoginController,用于接收前端請(qǐng)求

package org.hui.login.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author zenghui
 * @date 2020-05-20
 */
@Controller
public class LoginController {
    @RequestMapping("/")
    public String home() {
        return "home.html";
    }
    @RequestMapping("/login")
    public String login() {
        return "login.html";
    }
}

啟動(dòng)

運(yùn)行以下主程序

package org.hui.login;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author zenghui
 * @date 2020-05-20
 */
@SpringBootApplication
public class LoginApplication {
    public static void main(String[] args) {
        SpringApplication.run(LoginApplication.class, args);
    }
}

訪問 http://localhost:8080/login

顯示登錄頁面,輸入用戶名密碼,點(diǎn)擊登錄,即可看到效果。

完整代碼

Github

Gitee

以上就是Spring Security實(shí)現(xiàn)用戶名密碼登錄詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring Security用戶名密碼登錄的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++/java 繼承類的多態(tài)詳解及實(shí)例代碼

    C++/java 繼承類的多態(tài)詳解及實(shí)例代碼

    這篇文章主要介紹了C++/java 繼承類的多態(tài)詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 如何利用Spring把元素解析成BeanDefinition對(duì)象

    如何利用Spring把元素解析成BeanDefinition對(duì)象

    這篇文章主要介紹了如何利用Spring把元素解析成BeanDefinition對(duì)象,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • java避免多層嵌套循環(huán)用到的一些小技巧分享

    java避免多層嵌套循環(huán)用到的一些小技巧分享

    這篇文章主要介紹了java避免多層嵌套循環(huán)用到的一些小技巧分享,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • IDEA查看所有的斷點(diǎn)(Breakpoints)并關(guān)閉的方式

    IDEA查看所有的斷點(diǎn)(Breakpoints)并關(guān)閉的方式

    我們?cè)谑褂肐DEA開發(fā)Java應(yīng)用時(shí),基本上都需要進(jìn)行打斷點(diǎn)的操作,這方便我們排查BUG,也方便我們查看設(shè)計(jì)的是否正確,不過有時(shí)候,我們不希望進(jìn)入斷點(diǎn),所以我們需要快速關(guān)閉所有斷點(diǎn),故本文給大家介紹了IDEA查看所有的斷點(diǎn)(Breakpoints)并關(guān)閉的方式
    2024-10-10
  • java數(shù)據(jù)結(jié)構(gòu)-堆實(shí)現(xiàn)優(yōu)先隊(duì)列

    java數(shù)據(jù)結(jié)構(gòu)-堆實(shí)現(xiàn)優(yōu)先隊(duì)列

    通常都把隊(duì)列比喻成排隊(duì)買東西,大家都很守秩序,先排隊(duì)的人就先買東西。但是優(yōu)先隊(duì)列有所不同,它不遵循先進(jìn)先出的規(guī)則,而是根據(jù)隊(duì)列中元素的優(yōu)先權(quán),優(yōu)先權(quán)最大的先被取出,這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)-堆實(shí)現(xiàn)優(yōu)先隊(duì)列,感興趣的朋友一起看看吧
    2021-08-08
  • Java空指針異常處理之判空、Optional與Assert解析

    Java空指針異常處理之判空、Optional與Assert解析

    本文將深入探討三種處理空指針異常的方法:傳統(tǒng)的判空檢查、Java 8引入的Optional類以及使用斷言(Assert),通過代碼示例和應(yīng)用場(chǎng)景分析,幫助開發(fā)者理解并選擇最適合的方案以提升程序健壯性,感興趣的朋友一起看看吧
    2025-01-01
  • Spring Boot文件上傳原理與實(shí)現(xiàn)詳解

    Spring Boot文件上傳原理與實(shí)現(xiàn)詳解

    這篇文章主要介紹了Spring Boot 文件上傳原理與實(shí)現(xiàn)詳解,前端文件上傳是面向多用戶的,多用戶之間可能存在上傳同一個(gè)名稱、類型的文件;為了避免文件沖突導(dǎo)致的覆蓋問題這些應(yīng)該在后臺(tái)進(jìn)行解決,需要的朋友可以參考下
    2024-01-01
  • Java的IO流實(shí)現(xiàn)文件和文件夾的復(fù)制

    Java的IO流實(shí)現(xiàn)文件和文件夾的復(fù)制

    這篇文章主要為大家詳細(xì)介紹了Java的IO流實(shí)現(xiàn)文件和文件夾的復(fù)制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Springboot處理配置CORS跨域請(qǐng)求時(shí)碰到的坑

    Springboot處理配置CORS跨域請(qǐng)求時(shí)碰到的坑

    本篇文章介紹了我在開發(fā)過程中遇到的一個(gè)問題,以及解決該問題的過程及思路,通讀本篇對(duì)大家的學(xué)習(xí)或工作具有一定的價(jià)值,需要的朋友可以參考下
    2021-09-09
  • 在springboot中對(duì)kafka進(jìn)行讀寫的示例代碼

    在springboot中對(duì)kafka進(jìn)行讀寫的示例代碼

    本篇文章主要介紹了在springboot中對(duì)kafka進(jìn)行讀寫的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09

最新評(píng)論

镇雄县| 雷州市| 潼南县| 神农架林区| 侯马市| 上饶县| 河曲县| 昆明市| 定襄县| 贵南县| 西峡县| 濮阳市| 常熟市| 会泽县| 永丰县| 静海县| 岢岚县| 社旗县| 会泽县| 志丹县| 焦作市| 洛宁县| 五峰| 长葛市| 鹰潭市| 江都市| 阿尔山市| 马关县| 桂平市| 布尔津县| 黄石市| 门源| 杭锦后旗| 姚安县| 班戈县| 南阳市| 平泉县| 怀来县| 清涧县| 文成县| 金平|