1. 程式人生 > >SpringSecurity學習之基於資料庫的使用者認證

SpringSecurity學習之基於資料庫的使用者認證

  SpringSecurity給我們提供了一套最基本的認證方式,可是這種方式遠遠不能滿足大多數系統的需求。不過好在SpringSecurity給我們預留了許多可擴充套件的介面給我們,我們可以基於這些介面實現自己的認證方式。

一、前期準備工作

1.1、建立示例資料庫

Student表:

create table student
(
    id int auto_increment
        primary key,
    stuName varchar(8) null,
    password varchar(16) null,
    joinTime datetime
null, clz_id int null ) ;

Classes(班級)表:

create table classes
(
    id int auto_increment
        primary key,
    clz_name varchar(16) not null
)
;

1.2、新增相關依賴

compile group: 'mysql', name: 'mysql-connector-java'
compile group: 'org.springframework.security', name: 'spring-security-taglibs'
compile(
'org.springframework.boot:spring-boot-starter-jdbc')

二、實現步驟

2.1  定義Student類

package com.bdqn.lyrk.security.study.app.pojo;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

import java.sql.Timestamp;
import java.util.Collection;

public class Student extends User { private Timestamp joinTime; public Timestamp getJoinTime() { return joinTime; } public void setJoinTime(Timestamp joinTime) { this.joinTime = joinTime; } public Student(String username, String password, Collection<? extends GrantedAuthority> authorities) { super(username, password, authorities); } }
View Code

  在這裡定義的類繼承User,User是SpringSecurity裡的一個類,用以描述一個使用者和其最基本的屬性,當然我們要擴充套件它的使用者我們也可以實現UserDetails介面

2.2 實現UserDetailsService

package com.bdqn.lyrk.security.study.app.service;

import com.bdqn.lyrk.security.study.app.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
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.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class UserService implements UserDetailsService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User.UserBuilder users = User.withDefaultPasswordEncoder();
        Map<String, Object> map = jdbcTemplate.queryForMap("select t.clz_name,t1.stuName,t1.password,t1.joinTime from student t1 inner  join classes t on t.id = t1.clz_id where stuName = ?", username);
        Timestamp joinTime = null;
        if (map != null && map.size() > 0) {
            String stuName = (String) map.get("stuName");
            String password = (String) map.get("password");
            joinTime = (Timestamp) map.get("joinTime");
            String clzName = (String) map.get("clz_name");
            users.password(password);
            users.username(stuName);
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(clzName);
            List<GrantedAuthority> list = new ArrayList<>();
            list.add(authority);
            users.authorities(list);
        }
        UserDetails userDetails = users.build();
        Student student = new Student(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());
//        UserDetails userDetails = User.withDefaultPasswordEncoder().
        student.setJoinTime(joinTime);
        return student;
    }
}
View Code

  在這個接口裡我們要實現根據使用者名稱查詢使用者的方法,那麼一般情況下我們都會根據自己系統的使用者表來獲取使用者資訊,這裡面注意幾個方面:

  1)需要設定PasswordEncoder 

  2) 需要設定其角色資訊,那麼在這裡我用班級來表示使用者的角色

  3)使用者的三個重要屬性就是 使用者名稱,密碼與許可權

2.3 改造WebSecurityConfig

package com.bdqn.lyrk.security.study.app.config;

import com.bdqn.lyrk.security.study.app.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * spring-security的相關配置
 *
 * @author chen.nie
 * @date 2018/6/7
 **/
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /*
            1.配置靜態資源不進行授權驗證
            2.登入地址及跳轉過後的成功頁不需要驗證
            3.其餘均進行授權驗證
         */
        http.
                authorizeRequests().antMatchers("/static/**").permitAll().
                and().authorizeRequests().antMatchers("/user/**").hasRole("7022").
                and().authorizeRequests().anyRequest().authenticated().
                and().formLogin().loginPage("/login").successForwardUrl("/toIndex").permitAll()
                .and().logout().logoutUrl("/logout").invalidateHttpSession(true).deleteCookies().permitAll()
        ;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //設定自定義userService
        auth.userDetailsService(userService);
    }
}
View Code

在這裡主要做以下處理:

 1)針對於/user/**路徑的請求需要設定對應的許可權

 2) 做使用者登出的處理,使用者登出時需要銷燬session與cookie

 3)配置自定義UserDetailService

2.4、改造index.jsp

<%--
  Created by IntelliJ IDEA.
  User: chen.nie
  Date: 2018/6/8
  Time: 上午9:56
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
歡迎:${user.username}
<sec:authorize access="hasRole('7022')">
    加入時間:${user.joinTime}
</sec:authorize>
<form action="/logout" method="post">
    <input type="submit" value="退出" />
    <sec:csrfInput/>
</form>

</body>
</html>

  在這裡面我們使用spring對security標籤的支援判斷當前使用者是否有對應的角色,另外我們在處理登出操作時必須為post提交且有對應的token防止csrf

相關推薦

SpringSecurity學習基於資料庫的使用者認證

  SpringSecurity給我們提供了一套最基本的認證方式,可是這種方式遠遠不能滿足大多數系統的需求。不過好在SpringSecurity給我們預留了許多可擴充套件的介面給我們,我們可以基於這些介面實現自己的認證方式。 一、前期準備工作 1.1、建立示例資料庫 Student表: creat

三十七、python學習Redis資料庫

一、簡介 1.Nosql: 1.1.什麼是Nosql: 一類新出現的資料庫(not only sql),他的特點: (1)不支援 SQL語法。 (2)儲存結構跟傳統的關係型資料庫的那種關係表完全不同,nosql中儲存的資料都是鍵值對的形式。 (3)No

Android學習SQLite資料庫儲存

  今天學習sqlite資料庫儲存,sqlite資料庫是輕量級的,非常小,只有幾百K大小,非常 移動裝置使用,幾乎所有的手機使用的都是sqlite資料庫。   sqlite儲存的資料型別:.db   資料儲存的路徑:/data/data/packageName/d

十五、python學習MySQL資料庫(二):資料庫的操作

 一、資料庫的操作: 1.資料庫操作的概述: 在資料庫操作中,基本操作都是圍繞增刪改查來操作。簡稱CRUD C Create 建立 R Read/Retrieve 查詢 U Update 修改 D Delete 刪除 2.資料庫操作 在數操作資料庫時,所有的資料

十七、python學習MySQL資料庫(四): 資料庫程式設計

一、python資料庫操作: 1.資料庫程式設計概述: 資料庫程式設計就是針對資料庫的操作,通過編寫程式的方式,讓程式做為資料庫的客戶端進行資料庫操作。這種通過使用程式程式碼的方式去連線資料庫伺服器,通過和伺服器進行互動完成對資料庫的增刪改查的方式,就稱為資料庫程式設計。

Stoker的Java學習封裝資料庫連線工具類與commons-dbutils

Java學習之封裝資料庫連線工具類與commons-dbutils 一.封裝資料庫連結工具類 public class JDBCUitl { // 宣告連結 private static Connection connection; // 註冊驅動 st

遺傳演算法框架Geatpy學習——基於網格化處理的多種群進化優化及其在含等式約束的優化問題中的應用

Geatpy是由華南理工大學、華南農業大學、德州奧斯汀公立大學學生聯合團隊開發的一款Python上的遺傳和進化演算法高效能權威框架。其效能遠高於matlab遺傳演算法工具箱及類似的諸如gatbx、GEATbx、gaot等第三方工具箱。尤其適合需要應用遺傳或其他進化演算法求解建

Spring IoC學習基於XML的IoC

這裡實現一下基於XML方式的IoC,這裡沒有過多的理論,全是實際操作。 廢話不多說,直接寫程式碼。 這裡用的IDE是IDEA,用maven構建的專案,如果不會的依賴直接用jar包也行。先看專案結構和依賴。 這是專案結構使用maven構建的,如果不會直接構建簡單的java

go學習旅——資料庫配置及基本用例

golang強大的資料庫驅動 Go與PHP不同的地方是Go沒有官方提供資料庫驅動,而是為開發者開發資料庫驅動定義了一些標準介面,開發者可以 根據定義的介面來開發相應的資料庫驅動,這樣做有一個好處,只要按照標準介面開發的程式碼, 以後需要遷移資料 庫時,不需要任何

geotools學習連線資料庫並獲取資料

本文主要講連線postgis資料庫,並且獲得資料,這裡的資料不拘泥postgis資料庫 一、demo示例 package org.geotools.WPS; import java.io.IOException; import java.util.HashMap;

Android學習SQLite資料庫簡單測試例項

MyOpenDB.java檔案 package com.example.androidsqlite; import android.content.Context; import android.database.sqlite.SQLiteDatabase; impor

django學習包含資料庫的登入註冊功能

本文由本人原創,僅作為自己的學習記錄 這篇文章實現了簡單的登入註冊,登入驗證,session儲存登入狀態,cache快取,ajax接收後臺響應,利用{% csrf_token %}防止csrf跨站保護機制。 前端使用html+css+bootstrap+ajax實現,後端

Oracle學習建立資料庫(新建例項)

出處:http://blog.csdn.net/luiseradl/article/details/6972217 http://wenku.baidu.com/view/864b9b2c453610661ed9f469.html My points: (1)我的頭頭說一般不需要建立資料庫,在Orcl資料庫

spring security基於資料庫認證的原始碼分析

我們從研究org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.class的原始碼開始public class JdbcDaoImpl extends JdbcDaoSupport imp

RabbitMQ學習基於spring-rabbitmq的訊息非同步傳送

spring-rabbitmq的原始碼到http://github.com/momania/spring-rabbitmq下載,並可以下載例項程式碼。由於我使用的rabbitmq版本是3.0.4,部分程式碼做了調整。 具體例項如下(建立自動刪除非持久佇列): 1.資源配置a

爬蟲學習基於 Scrapy 的爬蟲自動登入

概述 在前面兩篇(爬蟲學習之基於Scrapy的網路爬蟲和爬蟲學習之簡單的網路爬蟲)文章中我們通過兩個實際的案例,採用不同的方式進行了內容提取。我們對網路爬蟲有了一個比較初級的認識,只要發起請求獲取響應的網頁內容,然後對內容進行格式化儲存。很多時候我們抓取到的內容可能會發生重複,

爬蟲學習基於Scrapy的網路爬蟲

在上一篇文章《爬蟲學習之一個簡單的網路爬蟲》中我們對爬蟲的概念有了一個初步的認識,並且通過Python的一些第三方庫很方便的提取了我們想要的內容,但是通常面對工作當作複雜的需求,如果都按照那樣的方式來處理效率非常的低,這通常需要你自己去定義並實現很多非常基礎的爬蟲框架上的功能,或者需要組合很多Python第

SpringSecurity學習自定義過濾器

  我們系統中的認證場景通常比較複雜,比如說使用者被鎖定無法登入,限制登入IP等。而SpringSecuriy最基本的是基於使用者與密碼的形式進行認證,由此可知它的一套驗證規範根本無法滿足業務需要,因此擴充套件勢在必行。那麼我們可以考慮自己定義filter新增至SpringSecurity的過濾器棧當中,來實

SpringSecurity學習快速上手

  網際網路專案中,安全與許可權控制是不可迴避的問題,為了解決這一些列問題,許多安全框架應運而生了。這些框架旨在幫我們解決公用的安全問題,讓我們的程式更加健壯,從而讓程式設計師全身心投入到業務開發當中。那麼SpringSecurity出自於大名鼎鼎的Spring家族,同時能與SpringBoot,Spring

IOS學習基於IOS7的tab bar

轉載請註明出處 http://blog.csdn.net/pony_maggie/article/details/28129473 作者:小馬 什麼是tabbar? 先幾張圖:      上圖中藍色框起來的部分就是tabbar, 它有如下幾個特徵: 1 它通