亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解spring security 配置多個AuthenticationProvider

 更新時間:2017年05月11日 09:56:13   作者:暮夜望日  
這篇文章主要介紹了詳解spring security 配置多個AuthenticationProvider ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

前言

發(fā)現(xiàn)很少關(guān)于spring security的文章,基本都是入門級的,配個UserServiceDetails或者配個路由控制就完事了,而且很多還是xml配置,國內(nèi)通病...so,本文里的配置都是java配置,不涉及xml配置,事實上我也不會xml配置

spring security的大體介紹

spring security本身如果只是說配置,還是很簡單易懂的(我也不知道網(wǎng)上說spring security難,難在哪里),簡單不需要特別的功能,一個WebSecurityConfigurerAdapter的實現(xiàn),然后實現(xiàn)UserServiceDetails就是簡單的數(shù)據(jù)庫驗證了,這個我就不說了。

spring security大體上是由一堆Filter(所以才能在spring mvc前攔截請求)實現(xiàn)的,F(xiàn)ilter有幾個,登出Filter(LogoutFilter),用戶名密碼驗證Filter(UsernamePasswordAuthenticationFilter)之類的,F(xiàn)ilter再交由其他組件完成細(xì)分的功能,例如最常用的UsernamePasswordAuthenticationFilter會持有一個AuthenticationManager引用,AuthenticationManager顧名思義,驗證管理器,負(fù)責(zé)驗證的,但AuthenticationManager本身并不做具體的驗證工作,AuthenticationManager持有一個AuthenticationProvider集合,AuthenticationProvider才是做驗證工作的組件,AuthenticationManager和AuthenticationProvider的工作機(jī)制可以大概看一下這兩個的java doc,然后成功失敗都有相對應(yīng)該Handler 。大體的spring security的驗證工作流程就是這樣了。

開始配置多AuthenticationProvider

首先,寫一個內(nèi)存認(rèn)證的AuthenticationProvider,這里我簡單地寫一個只有root帳號的AuthenticationProvider

package com.scau.equipment.config.common.security.provider;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * Created by Administrator on 2017-05-10.
 */
@Component
public class InMemoryAuthenticationProvider implements AuthenticationProvider {
  private final String adminName = "root";
  private final String adminPassword = "root";

  //根用戶擁有全部的權(quán)限
  private final List<GrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("CAN_SEARCH"),
      new SimpleGrantedAuthority("CAN_SEARCH"),
      new SimpleGrantedAuthority("CAN_EXPORT"),
      new SimpleGrantedAuthority("CAN_IMPORT"),
      new SimpleGrantedAuthority("CAN_BORROW"),
      new SimpleGrantedAuthority("CAN_RETURN"),
      new SimpleGrantedAuthority("CAN_REPAIR"),
      new SimpleGrantedAuthority("CAN_DISCARD"),
      new SimpleGrantedAuthority("CAN_EMPOWERMENT"),
      new SimpleGrantedAuthority("CAN_BREED"));

  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    if(isMatch(authentication)){
      User user = new User(authentication.getName(),authentication.getCredentials().toString(),authorities);
      return new UsernamePasswordAuthenticationToken(user,authentication.getCredentials(),authorities);
    }
    return null;
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return true;
  }

  private boolean isMatch(Authentication authentication){
    if(authentication.getName().equals(adminName)&&authentication.getCredentials().equals(adminPassword))
      return true;
    else
      return false;
  }
}

support方法檢查authentication的類型是不是這個AuthenticationProvider支持的,這里我簡單地返回true,就是所有都支持,這里所說的authentication為什么會有多個類型,是因為多個AuthenticationProvider可以返回不同的Authentication。

public Authentication authenticate(Authentication authentication) throws AuthenticationException 方法就是驗證過程。

如果AuthenticationProvider返回了null,AuthenticationManager會交給下一個支持authentication類型的AuthenticationProvider處理。

 另外需要一個數(shù)據(jù)庫認(rèn)證的AuthenticationProvider,我們可以直接用spring security提供的DaoAuthenticationProvider,設(shè)置一下UserServiceDetails和PasswordEncoder就可以了

 @Bean
  DaoAuthenticationProvider daoAuthenticationProvider(){
    DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
    daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
    daoAuthenticationProvider.setUserDetailsService(userServiceDetails);
    return daoAuthenticationProvider;
  }

最后在WebSecurityConfigurerAdapter里配置一個含有以上兩個AuthenticationProvider的AuthenticationManager,依然重用spring security提供的ProviderManager

package com.scau.equipment.config.common.security;

import com.scau.equipment.config.common.security.handler.AjaxLoginFailureHandler;
import com.scau.equipment.config.common.security.handler.AjaxLoginSuccessHandler;
import com.scau.equipment.config.common.security.provider.InMemoryAuthenticationProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.UserDetailsManagerConfigurer;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import java.util.Arrays;
import java.util.List;

/**
 * Created by Administrator on 2017/2/17.
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  UserDetailsService userServiceDetails;

  @Autowired
  InMemoryAuthenticationProvider inMemoryAuthenticationProvider;

  @Bean
  DaoAuthenticationProvider daoAuthenticationProvider(){
    DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
    daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
    daoAuthenticationProvider.setUserDetailsService(userServiceDetails);
    return daoAuthenticationProvider;
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .rememberMe().alwaysRemember(true).tokenValiditySeconds(86400).and()
        .authorizeRequests()
          .antMatchers("/","/*swagger*/**", "/v2/api-docs").permitAll()
          .anyRequest().authenticated().and()
        .formLogin()
          .loginPage("/")
          .loginProcessingUrl("/login")
          .successHandler(new AjaxLoginSuccessHandler())
          .failureHandler(new AjaxLoginFailureHandler()).and()
        .logout().logoutUrl("/logout").logoutSuccessUrl("/");
  }

  @Override
  public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/public/**", "/webjars/**", "/v2/**", "/swagger**");
  }

  @Override
  protected AuthenticationManager authenticationManager() throws Exception {
    ProviderManager authenticationManager = new ProviderManager(Arrays.asList(inMemoryAuthenticationProvider,daoAuthenticationProvider()));
    //不擦除認(rèn)證密碼,擦除會導(dǎo)致TokenBasedRememberMeServices因為找不到Credentials再調(diào)用UserDetailsService而拋出UsernameNotFoundException
    authenticationManager.setEraseCredentialsAfterAuthentication(false);
    return authenticationManager;
  }

  /**
   * 這里需要提供UserDetailsService的原因是RememberMeServices需要用到
   * @return
   */
  @Override
  protected UserDetailsService userDetailsService() {
    return userServiceDetails;
  }
}

基本上都是重用了原有的類,很多都是默認(rèn)使用的,只不過為了修改下行為而重新配置。其實如果偷懶,直接用一個UserDetailsService,在里面做各種認(rèn)證也是可以的~不過這樣就沒意思了

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot Session共享實現(xiàn)圖解

    SpringBoot Session共享實現(xiàn)圖解

    這篇文章主要介紹了SpringBoot Session共享實現(xiàn)圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • Java并發(fā)容器之ConcurrentLinkedQueue詳解

    Java并發(fā)容器之ConcurrentLinkedQueue詳解

    這篇文章主要介紹了Java并發(fā)容器之ConcurrentLinkedQueue詳解,加鎖隊列的實現(xiàn)較為簡單,這里就略過,我們來重點來解讀一下非阻塞隊列,
    從點到面, 下面我們來看下非阻塞隊列經(jīng)典實現(xiàn)類ConcurrentLinkedQueue,需要的朋友可以參考下
    2023-12-12
  • java文件和目錄的增刪復(fù)制

    java文件和目錄的增刪復(fù)制

    這篇文章主要為大家詳細(xì)介紹了java文件和目錄的增刪復(fù)制,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • java中char類型轉(zhuǎn)換成int類型的2種方法

    java中char類型轉(zhuǎn)換成int類型的2種方法

    這篇文章主要給大家介紹了關(guān)于java中char類型轉(zhuǎn)換成int類型的2種方法,因為java是一門強(qiáng)類型語言,所以在數(shù)據(jù)運(yùn)算中會存在類型轉(zhuǎn)換,需要的朋友可以參考下
    2023-07-07
  • springboot mybatis調(diào)用多個數(shù)據(jù)源引發(fā)的錯誤問題

    springboot mybatis調(diào)用多個數(shù)據(jù)源引發(fā)的錯誤問題

    這篇文章主要介紹了springboot mybatis調(diào)用多個數(shù)據(jù)源引發(fā)的錯誤問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Spring Boot Filter 過濾器的使用方式

    Spring Boot Filter 過濾器的使用方式

    這篇文章主要介紹了Spring Boot Filter 過濾器的使用方式,文章通過圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • 寧可用Lombok也不把成員設(shè)置為public原理解析

    寧可用Lombok也不把成員設(shè)置為public原理解析

    這篇文章主要為大家介紹了寧可用Lombok也不把成員設(shè)置為public原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 解決idea每次新建項目都需要重新指定maven目錄

    解決idea每次新建項目都需要重新指定maven目錄

    這篇文章主要介紹了解決idea每次新建項目都需要配置maven,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java轉(zhuǎn)JSON串的幾種方式

    Java轉(zhuǎn)JSON串的幾種方式

    本文給大家總結(jié)一下java轉(zhuǎn)json串的幾種方式,每種方式通過實例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-05-05
  • 淺談springMVC攔截器和過濾器總結(jié)

    淺談springMVC攔截器和過濾器總結(jié)

    本篇文章主要介紹了springMVC攔截器和過濾器總結(jié),可以用來對訪問的url進(jìn)行攔截處理,有興趣的可以了解一下。
    2017-01-01

最新評論