激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

云服務(wù)器|WEB服務(wù)器|FTP服務(wù)器|郵件服務(wù)器|虛擬主機(jī)|服務(wù)器安全|DNS服務(wù)器|服務(wù)器知識(shí)|Nginx|IIS|Tomcat|

服務(wù)器之家 - 服務(wù)器技術(shù) - 服務(wù)器知識(shí) - 基于Spring Security的身份驗(yàn)證與授權(quán)框架構(gòu)建指南

基于Spring Security的身份驗(yàn)證與授權(quán)框架構(gòu)建指南

2024-01-04 06:47未知服務(wù)器之家 服務(wù)器知識(shí)

環(huán)境:SpringBoot2.7.12 1. 簡(jiǎn)介 Spring Security是一個(gè)功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問控制框架,用于保護(hù)基于Spring的應(yīng)用程序。它采用AOP思想,基于servlet過濾器實(shí)現(xiàn)安全框架。 Spring Security具有以下優(yōu)勢(shì): 豐富的功能:Spring Se

環(huán)境:SpringBoot2.7.12

1. 簡(jiǎn)介

Spring Security是一個(gè)功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問控制框架,用于保護(hù)基于Spring的應(yīng)用程序。它采用AOP思想,基于servlet過濾器實(shí)現(xiàn)安全框架。

Spring Security具有以下優(yōu)勢(shì):

  • 豐富的功能:Spring Security提供了完善的認(rèn)證機(jī)制和方法級(jí)的授權(quán)功能,可以輕松地?cái)U(kuò)展以滿足自定義需求。
  • 強(qiáng)大的社區(qū)支持:與所有Spring項(xiàng)目一樣,Spring Security的真正強(qiáng)大之處在于可以輕松擴(kuò)展以滿足自定義要求。此外,它擁有一個(gè)活躍的社區(qū),提供了豐富的資源和支持。
  • 與Spring生態(tài)系統(tǒng)的集成:Spring Security與Spring生態(tài)系統(tǒng)中的其他組件緊密集成,如Spring MVC、Spring Boot等,使得在構(gòu)建安全應(yīng)用程序時(shí)更加便捷。
  • 高度可定制:Spring Security提供了大量的配置選項(xiàng)和擴(kuò)展點(diǎn),可以根據(jù)具體需求進(jìn)行定制。

本篇文章將會(huì)介紹常用的配置及相應(yīng)的擴(kuò)展點(diǎn)。

2. 實(shí)戰(zhàn)案例

2.1 自定義配置

在Spring Security5.7之前版本通過繼承WebSecurityConfigurerAdapter類

public class SecurityConfig extends WebSecurityConfigurerAdapter {
}

5.7之后版本

@Bean
public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http) throws Exception {
  // ...
}

在這里每定義一個(gè)SecurityFilterChain所注入的HttpSecurity都是唯一的實(shí)例對(duì)象。

后續(xù)所有的配置都是基于Spring Security5.7.8版本

2.2 自定義驗(yàn)證器

@Component
public class MemeryAuthticationProvider implements AuthenticationProvider {


  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication ;
    Object principal = token.getPrincipal() ;
    Object credentials = token.getCredentials() ;
    User user = users.get(principal) ;
    // notNull(user, "用戶名或密碼錯(cuò)誤") ;
    if (user == null) {
      return null ;
    }
    
    if (!user.getPassword().equals(credentials)) {
      throw new RuntimeException("密碼錯(cuò)誤") ;
    }
    return new UsernamePasswordAuthenticationToken(principal, credentials, user.getAuthorities()) ;
  }


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


}

通過上面自定義認(rèn)證器可以實(shí)現(xiàn)自己的驗(yàn)證邏輯。

2.2 自定義UserDetailsService

通過自定義UserDetailsService也可以實(shí)現(xiàn)對(duì)應(yīng)的邏輯,只不過這種方式你還需要提供一個(gè)PasswordEncoder

@Bean
public UserDetailsService userDetailsService() {
  return new UserDetailsService() {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
      return users.get(username) ;
    }
  };
}


@Bean
public PasswordEncoder passwordEncoder() {
  return new PasswordEncoder() {
    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
      return rawPassword.equals(encodedPassword) ;
    }
    @Override
    public String encode(CharSequence rawPassword) {
      return rawPassword.toString() ;
    }
  };
}

2.3 攔截指定路徑的請(qǐng)求

@Bean
public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http) throws Exception {
  http.csrf().disable() ;
  // 該過濾器鏈,只匹配/api/**路徑的請(qǐng)求
    http.requestMatcher(new AntPathRequestMatcher("/api/**")) ;
    // 也可以這樣配置多個(gè)
    // http.requestMatchers().antMatchers("/api/**", "/admin/**") ;
  // ...
  DefaultSecurityFilterChain chain = http.build();
  return chain ;
}

2.4 攔截指定路徑及權(quán)限

@Bean
public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http) throws Exception {
  http.csrf().disable() ;
  http.authorizeHttpRequests().requestMatchers(new AntPathRequestMatcher("/api/save")).hasAnyRole("C") ;
  http.authorizeHttpRequests().requestMatchers(new AntPathRequestMatcher("/api/find")).hasAuthority("ROLE_U") ;
  DefaultSecurityFilterChain chain = http.build();
  return chain ;
}

2.5 自定義授權(quán)決定

http.authorizeHttpRequests(registry -> {
  registry.antMatchers("/api/{id}").access(new AuthorizationManager<RequestAuthorizationContext>() {
    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication,
        RequestAuthorizationContext object) {
      Map<String, String> variables = object.getVariables() ;
      // 返回的路徑是/api/666則進(jìn)行攔截并且指定具有'D'的權(quán)限
      return new AuthorityAuthorizationDecision(variables.get("id").equals("666"), Arrays.asList(new SimpleGrantedAuthority("D"))) ;
    }
  }) ;
}) ;

2.6 自定義異常處理

http.exceptionHandling(customizer -> {
  customizer.accessDeniedHandler(new AccessDeniedHandler() {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response,
        AccessDeniedException accessDeniedException) throws IOException, ServletException {
      Map<String, Object> errors = new HashMap<>() ;
      response.setContentType("application/json;charset=utf-8") ;
      errors.put("code", -1) ;
      errors.put("status", response.getStatus()) ;
      errors.put("message", accessDeniedException.getMessage()) ;
      errors.put("details", ExceptionUtils.getMessage(accessDeniedException)) ;
      response.getWriter().println(new ObjectMapper().writeValueAsString(errors)) ;
    }
  }) ;
}) ;

2.7 自定義角色繼承

@Bean
public RoleHierarchy hierarchyVoter() {
  RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
  // ADMIN自動(dòng)擁有MANAGER的權(quán)限
  hierarchy.setHierarchy("ROLE_ADMIN > ROLE_MANAGER");
  return hierarchy ;
}

2.8 自定義退出登錄邏輯

http.logout().logoutUrl("/logout").addLogoutHandler(new LogoutHandler() {
  @Override
  public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
    System.out.println("退出登錄") ;
  }
}).logoutSuccessHandler(new LogoutSuccessHandler() {
  @Override
  public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
      throws IOException, ServletException {
    response.setContentType("text/html;charset=utf-8");
    PrintWriter out = response.getWriter() ;
    out.println("<h2>退出登錄成功</h2>") ;
    out.close() ; 
  }
}) ;

2.9 自定義登錄失敗邏輯

http
  .formLogin()
  .failureHandler(new AuthenticationFailureHandler() {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception
      response.setContentType("application/json;charset=UTF-8") ;
      PrintWriter out = response.getWriter() ;
      out.println("{\"code\": -1, \"message\": \"" + getRootCause(exception).getMessage() + "\"}") ;
      out.close();
    }
  });

2.10 自定義過濾器

@Bean
public PackAuthenticationFilter packAuthenticationFilter() {
  return new PackAuthenticationFilter() ;
}
// 添加自定義過濾器到Security Filter Chain中
http.addFilterBefore(packAuthenticationFilter(), RequestCacheAwareFilter.class) ;

2.11 配置多個(gè)過濾器鏈

@Bean
public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http) throws Exception {
  // 攔截/api/**
  http.requestMatcher(new AntPathRequestMatcher("/api/**")) ;
}
@Bean
public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http) throws Exception {
  // 攔截/admin/**
  http.requestMatcher(new AntPathRequestMatcher("/admin/**")) ;
}

2.12 開啟全局方法攔截

@Configuration
@EnableGlobalMethodSecurity(jsr250Enabled = true, prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {}
// 使用
@GetMapping("/find")
@PreAuthorize("hasRole('GUEST')")
public Object find(HttpServletResponse response) throws Exception {
  return "find method invoke..." ;
}

2.13 國(guó)際化支持

@Bean
public ReloadableResourceBundleMessageSource messageSource() {
  ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
  // 這里會(huì)按照順序查找的
  messageSource.addBasenames(
      "classpath:org/springframework/security/messages",
      "classpath:messages/messages"
  ) ;
  return messageSource ;
}

2.14 防止重復(fù)登錄

http.sessionManagement().maximumSessions(1).expiredSessionStrategy(new SessionInformationExpiredStrategy() {
  @Override
  public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {
    HttpServletResponse response = event.getResponse() ;
    response.setContentType("application/json;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("{\"code\": -1, \"message\": \"會(huì)話已過期,或重復(fù)登錄\"}");
    out.close();
  }
}) ;

注意:你的UserDetails必須重寫equals和hashCode方法

總結(jié):以上是在實(shí)際開發(fā)中經(jīng)常會(huì)應(yīng)用到的一些配置及相應(yīng)功能的使用。Spring Security是一個(gè)強(qiáng)大的安全認(rèn)證框架,它提供了豐富的安全功能來保護(hù)您的應(yīng)用程序。通過本文的基礎(chǔ)配置示例,你可以輕松地開始使用Spring Security來保護(hù)你的應(yīng)用程序并實(shí)現(xiàn)身份驗(yàn)證和授權(quán)功能。

完畢!!!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久草草亚洲蜜桃臀 | 鲁丝片一区二区三区免费入口 | 91一区二区三区久久久久国产乱 | 欧美日本在线视频 | 亚洲视频在线免费看 | 欧美精品一区二区中文字幕 | 黄视频网站免费 | av电影网站在线观看 | 日日做夜夜操 | 红杏亚洲影院一区二区三区 | 欧美成人免费在线视频 | 国产精品视频2021 | 97青青| 亚洲成人欧美在线 | 欧美成网 | 欧美一级特级 | 中文在线日韩 | 香蕉久久久精品 | 欧产日产国产精品v | 国产成人在线观看网站 | 免费人成在线播放 | 精品国产一区二区亚洲人成毛片 | 国产乱色精品成人免费视频 | 黄色片小说 | 国产青草视频在线观看 | 亚洲欧美日韩综合一区 | 护士hd老师fre0性xxx | 美国一级黄色毛片 | 免费国产自久久久久三四区久久 | 99久久精品免费看国产小宝寻花 | 羞羞色在线观看 | 欧美h版电影在线观看 | 午夜精品一区二区三区免费 | 亚洲精品一区二区三区在线看 | 成人福利视频在线观看 | 国产成人网 | 国产91av视频 | 亚洲成人福利电影 | 免费在线中文字幕 | 羞羞视频免费网站日本动漫 | 国产日韩亚洲 |