国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【SpringSecurity系列01】初識SpringSecurity

elva / 2687人閱讀

摘要:什么是是一個能夠為基于的企業(yè)應用系統提供聲明式的安全訪問控制解決方案的安全框架。它來自于,那么它與整合開發(fā)有著天然的優(yōu)勢,目前與對應的開源框架還有。通常大家在做一個后臺管理的系統的時候,應該采用判斷用戶是否登錄。

? 什么是SpringSecurity

?      Spring Security是一個能夠為基于Spring的企業(yè)應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面編程)功能,為應用系統提供聲明式的安全訪問控制功能,減少了為企業(yè)系統安全控制編寫大量重復代碼的工作。

以上來介紹來自wiki,比較官方。

? 用自己的話 簡單介紹一下,Spring Security 基于 Servlet 過濾器鏈的形式,為我們的web項目提供認證授權服務。它來自于Spring,那么它與SpringBoot整合開發(fā)有著天然的優(yōu)勢,目前與SpringSecurity對應的開源框架還有shiro。接下來我將通過一個簡單的例子帶大家來認識SpringSecurity,然后通過分析它的源碼帶大家來認識一下SpringSecurity是如何工作,從一個簡單例子入門,大家由淺入深的了解學習SpringSecurity

通常大家在做一個后臺管理的系統的時候,應該采用session判斷用戶是否登錄。我記得我在沒有接觸學習SpringSecurity與shiro之前。對于用戶登錄功能實現通常是如下:

public String login(User user, HttpSession session){
  //1、根據用戶名或者id從數據庫讀取數據庫中用戶
  //2、判斷密碼是否一致
      //3、如果密碼一致
          session.setAttribute("user",user);
      //4、否則返回登錄頁面
  
}

對于之后那些需要登錄之后才能訪問的url,通過SpringMvc的攔截器中的#preHandle來判斷session中是否有user對象
如果沒有 則返回登錄頁面
如果有, 則允許訪問這個頁面。

但是在SpringSecurity中,這一些邏輯已經被封裝起來,我們只需要簡單的配置一下就能使用。

接下來我通過一個簡單例子大家認識一下SpringSecurity

本文基于SpringBoot,如果大家對SpringBoot不熟悉的話可以看看我之前寫的SpringBoot入門系列

我使用的是:

SpringBoot 2.1.4.RELEASE

SpringSecurity 5



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.4.RELEASE
         
    
    com.yukong
    springboot-springsecurity
    0.0.1-SNAPSHOT
    springboot-springsecurity
    springboot-springsecurity study

    
        1.8
    

    
        
            org.springframework.boot
            spring-boot-starter-security
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.0.1
        
        
            mysql
            mysql-connector-java
            runtime
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.security
            spring-security-test
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


配置一下數據庫 以及MyBatis

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&characterEncoding=utf8
    password: abc123
mybatis:
  mapper-locations: classpath:mapper/*.xml

這里我用的MySQL8.0 大家注意一下 MySQL8.0的數據庫驅動的類的包改名了

在前面我有講過SpringBoot中如何整合Mybatis,在這里我就不累述,有需要的話看這篇文章

user.sql

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT "主鍵",
  `username` varchar(32) NOT NULL COMMENT "用戶名",
  `svc_num` varchar(32) DEFAULT NULL COMMENT "用戶號碼",
  `password` varchar(100) DEFAULT NULL COMMENT "密碼",
  `cust_id` bigint(20) DEFAULT NULL COMMENT "客戶id  1對1",
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

對應的UserMapper.java

package com.yukong.mapper;

import com.yukong.entity.User;

/**
 *
 * @author yukong
 * @date 2019-04-11 16:50
 */
public interface UserMapper {

    int insertSelective(User record);

    User selectByUsername(String  username);


}

UserMapper.xml




  
    
    
    
    
    
  
  
    id, username, svc_num, `password`, cust_id
  
  

  
    insert into user
    
      
        username,
      
      
        svc_num,
      
      
        `password`,
      
      
        cust_id,
      
    
    
      
        #{username,jdbcType=VARCHAR},
      
      
        #{svcNum,jdbcType=VARCHAR},
      
      
        #{password,jdbcType=VARCHAR},
      
      
        #{custId,jdbcType=BIGINT},
      
    
  

在這里我們定義了兩個方法。

國際慣例ctrl+shift+t創(chuàng)建mapper的測試方法,并且插入一條記錄

package com.yukong.mapper;

import com.yukong.SpringbootSpringsecurityApplicationTests;
import com.yukong.entity.User;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;

import static org.junit.Assert.*;

/**
 * @author yukong
 * @date 2019-04-11 16:53
 */

public class UserMapperTest extends SpringbootSpringsecurityApplicationTests {


    @Autowired
    private UserMapper userMapper;


    @Test
    public void insert() {
        User user = new User();
        user.setUsername("yukong");
        user.setPassword("abc123");
        userMapper.insertSelective(user);
    }

}

運行測試方法,并且成功插入一條記錄。

創(chuàng)建UserController.java

package com.yukong.controller;

import com.yukong.entity.User;
import com.yukong.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author yukong
 * @date 2019-04-11 15:22
 */
@RestController
public class UserController {
    
    @Autowired
    private UserMapper userMapper;

    @RequestMapping("/user/{username}")
    public User hello(@PathVariable String username) {
        return userMapper.selectByUsername(username);
    }

}

這個方法就是根據用戶名去數據庫查找用戶詳細信息。

啟動。因為我們之前插入過一條username=yukong的記錄,所以我們查詢一下,訪問127.0.0.1:8080/user/yukong

[圖片上傳失敗...(image-ea02ac-1554981869345)]

我們可以看到 我們被重定向到了一個登錄界面,這也是我們之前引入的spring-boot-security-starter起作用了。

大家可能想問了,用戶名跟密碼是什么,用戶名默認是user,密碼在啟動的時候已經通過日志打印在控制臺了。

現在我們輸入用戶跟密碼并且登錄。就可以成功訪問我們想要訪問的接口。

從這里我們可以知道,我只需要引入了Spring-Security的依賴,它就開始生效,并且保護我們的接口了,但是現在有一個問題就是,它的用戶名只能是user并且密碼是通過日志打印在控制臺,但是我們希望它能通過數據來訪問我們的用戶并且判斷登錄。

其實想實現這個功能也很簡單。這里我們需要了解兩個接口。

UserDetails

UserDetailsService

所以,我們需要將我們的User.java實現這個接口

package com.yukong.entity;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

/**
 *
 * @author yukong
 * @date 2019-04-11 16:50
 */
public class User implements UserDetails {
    /**
    * 主鍵
    */
    private Long id;

    /**
    * 用戶名
    */
    private String username;

    /**
    * 用戶號碼
    */
    private String svcNum;

    /**
    * 密碼
    */
    private String password;

    /**
    * 客戶id  1對1
    */
    private Long custId;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

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

    @Override
    public boolean isAccountNonExpired() {
        return false;
    }

    @Override
    public boolean isAccountNonLocked() {
        return false;
    }

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

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

    public void setUsername(String username) {
        this.username = username;
    }

    public String getSvcNum() {
        return svcNum;
    }

    public void setSvcNum(String svcNum) {
        this.svcNum = svcNum;
    }

    @Override
    public Collection getAuthorities() {
        // 這里我們沒有用到權限,所以返回一個默認的admin權限
        return AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
    }

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

    public void setPassword(String password) {
        this.password = password;
    }

    public Long getCustId() {
        return custId;
    }

    public void setCustId(Long custId) {
        this.custId = custId;
    }
}

接下來我們再看看UserDetailsService

它只有一個方法的聲明,就是通過用戶名去查找用戶信息,從這里我們應該知道了,SpringSecurity回調UserDetails#loadUserByUsername去獲取用戶,但是它不知道用戶信息存在哪里,所以定義成接口,讓使用者去實現。在我們這個項目用 我們的用戶是存在了數據庫中,所以我們需要調用UserMapper的方法去訪問數據庫查詢用戶信息。這里我們新建一個類叫MyUserDetailsServiceImpl

package com.yukong.config;

import com.yukong.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.Service;

/**
 * @author yukong
 * @date 2019-04-11 17:35
 */
@Service
public class MyUserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return userMapper.selectByUsername(username);
    }
}

然后新建一個類去把我們的UserDetailsService配置進去

這里我們新建一個SecurityConfig

package com.yukong.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author yukong
 * @date 2019-04-11 15:08
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;


    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // 配置UserDetailsService 跟 PasswordEncoder 加密器
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
        auth.eraseCredentials(false);
    }
}

在這里我們還配置了一個PasswordEncoder加密我們的密碼,大家都知道密碼明文存數據庫是很不安全的。

接下里我們插入一條記錄,需要注意的是 密碼需要加密。

package com.yukong.mapper;

import com.yukong.SpringbootSpringsecurityApplicationTests;
import com.yukong.entity.User;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;

import static org.junit.Assert.*;

/**
 * @author yukong
 * @date 2019-04-11 16:53
 */

public class UserMapperTest extends SpringbootSpringsecurityApplicationTests {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserMapper userMapper;


    @Test
    public void insert() {
        User user = new User();
        user.setUsername("yukong");
        user.setPassword(passwordEncoder.encode("abc123"));
        userMapper.insertSelective(user);
    }

}

接下來啟動程序,并且登錄,這次只需要輸入插入到數據中的那條記錄的用戶名跟密碼即可。

在這里一節(jié)中,我們了解到如何使用springsecurity 完成一個登錄功能,接下我們將通過分析源碼來了解為什么需要這個配置,以及SpringSecurity的工作原理是什么。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77554.html

相關文章

  • 兩年了,我寫了這些干貨!

    摘要:開公眾號差不多兩年了,有不少原創(chuàng)教程,當原創(chuàng)越來越多時,大家搜索起來就很不方便,因此做了一個索引幫助大家快速找到需要的文章系列處理登錄請求前后端分離一使用完美處理權限問題前后端分離二使用完美處理權限問題前后端分離三中密碼加鹽與中異常統一處理 開公眾號差不多兩年了,有不少原創(chuàng)教程,當原創(chuàng)越來越多時,大家搜索起來就很不方便,因此做了一個索引幫助大家快速找到需要的文章! Spring Boo...

    huayeluoliuhen 評論0 收藏0
  • SpringSecurity01(springSecurity執(zhí)行流程02)

    摘要:里面配置的過濾器鏈當用戶使用表單請求時進入返回一個的實例一般是從數據庫中查詢出來的實例然后直接到最后一個如果有錯則拋錯給前面一個進行拋錯如果沒有錯則放行可以訪問對應的資源上面是總的執(zhí)行流程下面單獨說一下的認證流程這個圖應該都看得懂和里面的配 showImg(https://segmentfault.com/img/bVbvO0O?w=1258&h=261);web.xml里面配置的過濾...

    Dr_Noooo 評論0 收藏0
  • SpringSecurity01(使用傳統的xml方式開發(fā),且不連接數據庫)

    摘要:創(chuàng)建一個工程在里面添加依賴,依賴不要隨便改我改了出錯了好幾次都找不到原因可以輕松的將對象轉換成對象和文檔同樣也可以將轉換成對象和配置 1.創(chuàng)建一個web工程2.在pom里面添加依賴,依賴不要隨便改,我改了出錯了好幾次都找不到原因 UTF-8 1.7 1.7 2.5.0 1.2 3.0-alpha-1 ...

    Gilbertat 評論0 收藏0
  • SpringSecurity系列02】SpringSecurity 表單認證邏輯源碼解讀

    摘要:通過上面我們知道對于表單登錄的認證請求是交給了處理的,那么具體的認證流程如下從上圖可知,繼承于抽象類。中維護這一個對象列表,通過遍歷判斷并且最后選擇對象來完成最后的認證。發(fā)布一個登錄事件。 概要 前面一節(jié),通過簡單配置即可實現SpringSecurity表單認證功能,而今天這一節(jié)將通過閱讀源碼的形式來學習SpringSecurity是如何實現這些功能, 前方高能預警,本篇分析源碼篇幅較...

    zzir 評論0 收藏0

發(fā)表評論

0條評論

elva

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<