国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

云服務器|WEB服務器|FTP服務器|郵件服務器|虛擬主機|服務器安全|DNS服務器|服務器知識|Nginx|IIS|Tomcat|

服務器之家 - 服務器技術 - 服務器安全 - 基于Spring Security的身份驗證與授權框架構建指南

基于Spring Security的身份驗證與授權框架構建指南

2024-01-04 04:07未知服務器之家 服務器安全

環境:SpringBoot2.7.12 1. 簡介 Spring Security是一個功能強大且高度可定制的身份驗證和訪問控制框架,用于保護基于Spring的應用程序。它采用AOP思想,基于servlet過濾器實現安全框架。 Spring Security具有以下優勢: 豐富的功能:Spring Se

環境:SpringBoot2.7.12

1. 簡介

Spring Security是一個功能強大且高度可定制的身份驗證和訪問控制框架,用于保護基于Spring的應用程序。它采用AOP思想,基于servlet過濾器實現安全框架。

Spring Security具有以下優勢:

  • 豐富的功能:Spring Security提供了完善的認證機制和方法級的授權功能,可以輕松地擴展以滿足自定義需求。
  • 強大的社區支持:與所有Spring項目一樣,Spring Security的真正強大之處在于可以輕松擴展以滿足自定義要求。此外,它擁有一個活躍的社區,提供了豐富的資源和支持。
  • 與Spring生態系統的集成:Spring Security與Spring生態系統中的其他組件緊密集成,如Spring MVC、Spring Boot等,使得在構建安全應用程序時更加便捷。
  • 高度可定制:Spring Security提供了大量的配置選項和擴展點,可以根據具體需求進行定制。

本篇文章將會介紹常用的配置及相應的擴展點。

2. 實戰案例

2.1 自定義配置

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

public class SecurityConfig extends WebSecurityConfigurerAdapter {
}

5.7之后版本

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

在這里每定義一個SecurityFilterChain所注入的HttpSecurity都是唯一的實例對象。

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

2.2 自定義驗證器

@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, "用戶名或密碼錯誤") ;
    if (user == null) {
      return null ;
    }
    
    if (!user.getPassword().equals(credentials)) {
      throw new RuntimeException("密碼錯誤") ;
    }
    return new UsernamePasswordAuthenticationToken(principal, credentials, user.getAuthorities()) ;
  }


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


}

通過上面自定義認證器可以實現自己的驗證邏輯。

2.2 自定義UserDetailsService

通過自定義UserDetailsService也可以實現對應的邏輯,只不過這種方式你還需要提供一個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 攔截指定路徑的請求

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

2.4 攔截指定路徑及權限

@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 自定義授權決定

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則進行攔截并且指定具有'D'的權限
      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自動擁有MANAGER的權限
  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 配置多個過濾器鏈

@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 國際化支持

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

2.14 防止重復登錄

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\": \"會話已過期,或重復登錄\"}");
    out.close();
  }
}) ;

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

總結:以上是在實際開發中經常會應用到的一些配置及相應功能的使用。Spring Security是一個強大的安全認證框架,它提供了豐富的安全功能來保護您的應用程序。通過本文的基礎配置示例,你可以輕松地開始使用Spring Security來保護你的應用程序并實現身份驗證和授權功能。

完畢!!!

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 欧美日韩精品一区二区三区蜜桃 | 欧美在线高清 | 亚洲免费视频观看 | 中文二区 | 午夜伦理影院 | 欧美一级高清在线 | 午夜精品在线 | 精品亚洲一| 欧美激情精品久久久久久 | 午夜精品久久久久久久久 | 精精国产xxxx视频在线观看 | 自拍亚洲| 久草久| 一区二区三区在线看 | 特污影院 | 国产精品亚洲综合 | 91在线精品一区二区三区 | 黄色免费视频 | 黄色网页在线观看 | 日本中文字幕一区 | 久久99精品久久久久久水蜜桃 | 国产不卡免费视频 | 欧美成人免费 | 欧美精品一区在线 | 欧美国产日韩一区 | av国产精品| 免费操片| 精品综合99久久久久久www | 国产一区二区三区视频在线观看 | 精品欧美一区二区三区久久久 | 久久人人爽人人爽人人片亚洲 | 不卡一区 | 看亚洲a级一级毛片 | 欧洲一级毛片 | 亚洲资源在线 | 在线播放视频一区 | 激情五月婷婷基地 | 国产成人精品一区二区三区网站观看 | 黄色一级片在线观看 | 国产综合精品一区二区三区 | 高清一区二区三区 |