一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術(shù)|正則表達(dá)式|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - 詳解spring security 配置多個(gè)AuthenticationProvider

詳解spring security 配置多個(gè)AuthenticationProvider

2020-09-29 10:53暮夜望日 JAVA教程

這篇文章主要介紹了詳解spring security 配置多個(gè)AuthenticationProvider ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

前言

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

spring security的大體介紹

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

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

開(kāi)始配置多AuthenticationProvider

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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的類型是不是這個(gè)AuthenticationProvider支持的,這里我簡(jiǎn)單地返回true,就是所有都支持,這里所說(shuō)的authentication為什么會(huì)有多個(gè)類型,是因?yàn)槎鄠€(gè)AuthenticationProvider可以返回不同的Authentication。

public Authentication authenticate(Authentication authentication) throws AuthenticationException 方法就是驗(yàn)證過(guò)程。

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

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

?
1
2
3
4
5
6
7
@Bean
 DaoAuthenticationProvider daoAuthenticationProvider(){
   DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
   daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
   daoAuthenticationProvider.setUserDetailsService(userServiceDetails);
   return daoAuthenticationProvider;
 }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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)證密碼,擦除會(huì)導(dǎo)致TokenBasedRememberMeServices因?yàn)檎也坏紺redentials再調(diào)用UserDetailsService而拋出UsernameNotFoundException
    authenticationManager.setEraseCredentialsAfterAuthentication(false);
    return authenticationManager;
  }
 
  /**
   * 這里需要提供UserDetailsService的原因是RememberMeServices需要用到
   * @return
   */
  @Override
  protected UserDetailsService userDetailsService() {
    return userServiceDetails;
  }
}

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://www.cnblogs.com/scau-chm/p/6836748.html?utm_source=tuicool&utm_medium=referral

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲成年男人的天堂网 | 高清视频在线播放 | 91制片厂制作传媒免费版樱花 | 精品湿| 色老板影视 | 日本成人黄色网址 | 日韩亚洲国产激情在线观看 | 亚洲免费二区 | 精品免费看 | 97超pen个人视频公开视频视 | juliaann大战两个黑人 | 日韩手机在线视频 | 欧美疯狂做爰xx | 无码AV免费精品一区二区三区 | 日本高清视频在线的 | 波多野结衣在线中文字幕 | 成人猫咪maomiav永久网址 | 成人1234| 欧美午夜精品 | 911精品国产亚洲日本美国韩国 | 九九精品影院 | 特黄特色大片免费高清视频 | 男女性潮高片无遮挡禁18 | 日本在线观看视频 | re99| 日出水了特别黄的视频 | 成人在线免费观看视频 | 91嫩草国产在线观看免费 | 亚洲欧美一区二区久久 | 叛佛 作者满栀小说免费阅读 | 欧美成人aa | 国产免费资源高清小视频在线观看 | 日本在线看 | 好姑娘在线视频观看免费 | 成人aqq | 久久精品观看影院2828 | 国产巨大bbbb俄罗斯 | 久久成人亚洲 | 俄罗斯bbbbbbxxxxxx | 亚洲精品国产在线网站 | 国产午夜精品久久理论片 |