91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解SpringSecurity原理認證

發布時間:2021-10-12 09:22:17 來源:億速云 閱讀:162 作者:iii 欄目:編程語言

本篇內容主要講解“如何理解SpringSecurity原理認證”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何理解SpringSecurity原理認證”吧!

項目結構基本沒有變:

首先我們需要實現UserDetailsService,來獲取用戶相關的信息封裝類UserDetails。

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;


@Service
public class MyUserDetailService implements UserDetailsService {

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//		SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority("admin");
        // 這里可以訪問數據庫、緩存等獲取用戶信息,然后構建為User,User是UserDetails的實現類
		return User.builder()
				.username("bob")//用戶名
                //密碼 111111 通過BCryptPasswordEncoder加密之后的密文
				.password("$2a$10$344aKAgXr17q7u.8l5i7Cu8wUJr/cxBIniLsVtf/WwFrPx0khY62K")
				.authorities("admin")//權限信息
				.build();
	}
}

UserDetailsService只做一件事情,就是獲取UserDetails,主要是用戶名、密碼和權限。可以使用Spring Security為我們提供的實現類User,也可以自己實現UserDetails,按自己需求封裝。

有了怎樣獲取UserDetails的方法,我們當然還要通過SecurityConfig配置的AuthenticationManagerBuilder告訴Spring Security。

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.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import vip.oschool.uinion.security.MyUserDetailService;

import javax.annotation.Resource;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Resource
	MyUserDetailService myUserDetailService;

	@Bean
	BCryptPasswordEncoder bCryptPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}

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

注意,我們同時還添加了一個BCryptPasswordEncoder,這是一個密碼加密器,因為一般情況數據庫存放的都是密碼的密文,所以,我們還要告訴Spring Security,我們數據庫的密碼的加密方式是什么,這樣Spring Security才能把從客戶端接收到的密碼使用同樣的方式加密,然后做認證。

當然,你也可以通過下面的方式來設置密碼加密器:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(myUserDetailService).passwordEncoder(new BCryptPasswordEncoder());
}

下面我們把配置文件中的用戶名和密碼注釋掉,重新啟動,然后就可以通過我們在UserDetailsService實現中設置的用戶bob和密碼111111來完成認證。

server:
  port: 8081

#spring:
#    security:
#      user:
#        name: tim
#        password: 111111

Principal

一個比較抽象的概念,用于唯一標識實體的類。

例如,對于用戶來說:用戶id、手機號、郵箱就可以作為用戶的principal來標志用戶。

Credentials

簡單點理解,就可以看做是密碼。

GrantedAuthority

先知道是:角色與權限,具體的后面詳細介紹。

UserDetails

用戶實體的接口,通過這個接口可以獲取:

  • getPassword: 獲取密碼

  • getUserName: 獲取用戶名

  • isEnabled: 賬戶是否可用

  • isAccountNonExpired: 賬戶是否過期

  • isAccountNonLocked: 賬戶是否被鎖定

  • isCredentialsNonExpired: 密碼是否過期

  • getAuthorites:獲取用戶權限,本質上是用戶的角色信息

Spring Security中是:org.springframework.security.core.userdetails.UserDetails

Spring Security提供了一個默認的實現類:org.springframework.security.core.userdetails.User

UserDetailsService

這個接口只有一個目的,就是獲取UserDetails,例如,我們需要從數據庫獲取用戶,就需要實現這個接口,并把實現類注入到Spring容器中。

只需要獲取UserDetails,認證的工作Spring Security自己獲通過用戶名和密碼來驗證,中間可能還涉及一下密碼處理的過程。

Authentication

用于存儲用戶認證詳細信息:principal、權限GrantedAuthority等。

自定義的Authentication可以實現Authentication接口,也可以直接繼承AbstractAuthenticationToken。

如何理解SpringSecurity原理認證

import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;

import java.util.Collection;

public class JwtAuthenticationToken extends AbstractAuthenticationToken {

    public JwtAuthenticationToken(Collection<? extends GrantedAuthority> authorities) {
        super(authorities);
    }

    @Override
    public Object getCredentials() {
        return null;
    }

    @Override
    public Object getPrincipal() {
        return null;
    }
}

AuthenticationProvider

AuthenticationProvider,顧名思義,認證的提供者,就是用于執行特定類型的身份認證的接口。

我們如果要自定義認證,就需要實現這個接口,例如,現在很多前后端分離項目使用JWT方式來鑒權,那每個請求怎樣校驗Token呢?

我們就可以創建一個JWTAuthenticationProvider實現AuthenticationProvider,來完成JWT token的認證工作。

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

public class JwtAuthenticationProvider implements AuthenticationProvider {
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.isAssignableFrom(JwtAuthenticationToken.class);
    }
}

然后可以通過下面的方式把我們自定義的AuthenticationProvider注入。

@EnableWebSecurity()
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
  @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(daoAuthenticationProvider())
                .authenticationProvider(jwtAuthenticationProvider());
    }
}

前面,我們使用的UserDetailService為什么能生效,是因為做了下面的配置:

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

認證管理器構建者AuthenticationManagerBuilder的userDetailsService會創建一個DaoAuthenticationProvider,DaoAuthenticationProvider使用DelegatingPasswordEncoder的是一個代理,默認使用的是BCryptPasswordEncoder。

AuthenticationManager與ProviderManager

AuthenticationManager,顧名思義,是用來管理Authentication,其實是管理AuthenticationProvider。

ProviderManager是AuthenticationManager的實現類,它持有一個AuthenticationProvider列表,用來完成不同的認證。

它還持有一個AuthenticationManager的引用,作為其父類。

一般來說我們使用ProviderManager就夠了,一般也只需要一個AuthenticationProvider。

如果要配置多個,可以在SecurityConfig(繼承了WebSecurityConfigurerAdapter)重寫authenticationManager。

 @Override
protected AuthenticationManager authenticationManager() {
    // ProviderManager可以設置多個AuthenticationProvider
    ProviderManager authenticationManager = new ProviderManager(Arrays.asList());
    return authenticationManager;
}

PasswordEncoder

簡單的說就是用于對密碼進行加密,存儲用戶密碼的明文絕對不是什么好的習慣,這是對用戶的不負責任,也是項目存在風險。

所以,我們一般都會對用戶的密碼進行加密之后再存儲,通常的做法是加鹽然后使用sha256再md5之類的算法。

使用Spring Security就需要我們自己實現這些過程了,直接配置PasswordEncoder就可以了。

Spring Security為PasswordEncoder提供了下面一些實現類。

DelegatingPasswordEncoder

即委托密碼編碼器,兼容多種不同加密方式存儲密碼。主要用于新舊數據的加密方式的兼容,做到平滑遷移,例如舊數據使用NoOpPasswordEncoder,新數據使用BCryptPasswordEncoder加密。

BCryptPasswordEncoder

基于bcrypt算法的編碼器,為了使其更能抵御密碼破解,bcrypt故意降低了速度,與其他自適應單向功能一樣,應將其調整為大約1秒鐘,以驗證系統上的密碼。BCryptPasswordEncoder的默認實現使用強度10。

Argon2PasswordEncoder

基于 Argon2算法的編碼器,Argon2是一種故意慢速的算法,需要大量內存。 與其他自適應單向功能一樣,應將其調整為大約1秒鐘,以驗證系統上的密碼。 Argon2PasswordEncoder的當前實現需要BouncyCastle。

Pbkdf2PasswordEncoder

基于 PBKDF2算法的編碼器,為了克服密碼破解問題,PBKDF2是一種故意緩慢的算法。 與其他自適應單向功能一樣,應將其調整為大約1秒鐘,以驗證系統上的密碼。 當需要FIPS認證時,此算法是一個不錯的選擇。

SCryptPasswordEncoder

基于scrypt算法的編碼器, 為了克服自定義硬件scrypt上的密碼破解問題,這是一種故意緩慢的算法,需要大量內存。 與其他自適應單向功能一樣,應將其調整為大約1秒鐘,以驗證系統上的密碼。

添加測試用戶

我們測試的時候,想要添加測試用戶,但是又不想太麻煩的去實現UserDetailsService,也可以通過下面的方式:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.inMemoryAuthentication()
				.withUser("tim")
				.password("111111").roles("admin")
				.and()
				.withUser("allen")
				.password("222222")
				.roles("user");
	}
}

進入inMemoryAuthentication方法,我們可以看到上面的方式等價于:

@Bean
public UserDetailsService userDetailsService() {
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    manager.createUser(User.withUsername("tim").password("111111").roles("admin").build());
    manager.createUser(User.withUsername("allen").password("222222").roles("user").build());
    return manager;
}

所以,本質上還是相當于創建了一個UserDetailsService,只不過數據保存在內存中。

到此,相信大家對“如何理解SpringSecurity原理認證”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

三穗县| 阿尔山市| 新余市| 包头市| 娄底市| 北海市| 和田县| 安乡县| 栾川县| 洞头县| 栾城县| 邯郸市| 洪江市| 三河市| 昂仁县| 讷河市| 浦北县| 靖江市| 年辖:市辖区| 山丹县| 东至县| 五家渠市| 常德市| 宜良县| 黄山市| 昆明市| 三原县| 邢台市| 泗洪县| 天台县| 罗田县| 从化市| 宁德市| 武冈市| 南丰县| 万载县| 奉贤区| 广宗县| 达尔| 修文县| 随州市|