Spring Security

2020-04-13  本文已影响0人  MlLance
  1. 原理
    Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它是用于保护基于Spring的应用程序的实际标准。
    Spring Security是一个框架,致力于为Java应用程序提供身份验证和授权。与所有Spring项目一样,Spring Security的真正强大之处在于可以轻松扩展以满足自定义要求
image.png

Spring Security的体系结构旨在将身份验证与授权分开,并具有策略和扩展点。

1.身份验证


public interface AuthenticationManager {

  Authentication authenticate(Authentication authentication)
    throws AuthenticationException;

}

authenticate()方法中的三件事之一:

//An AuthenticationProvider有点像an,AuthenticationManager但是它有一个额外的方法,允许调用者查询是否支持给定Authentication类型:
public interface AuthenticationProvider {

    Authentication authenticate(Authentication authentication)
            throws AuthenticationException;
/**
*
*/
    boolean supports(Class<?> authentication);

}
@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

  @Autowired
  DataSource dataSource;

   ... // web stuff here

  @Override
  public void configure(AuthenticationManagerBuilder builder) {
    builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
      .password("secret").roles("USER");
  }

}

2.访问控制

安全过滤器链 WebSecurityConfigurerAdapter

笔记:
5.1。认证方式
5.1.1。认证支持
5.1.2。密码储存

//.创建默认的DelegatingPasswordEncoder
PasswordEncoder passwordEncoder =
    PasswordEncoderFactories.createDelegatingPasswordEncoder();
//创建自定义DelegatingPasswordEncoder
String idForEncode = "bcrypt";
Map encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("sha256", new StandardPasswordEncoder());
PasswordEncoder passwordEncoder =
    new DelegatingPasswordEncoder(idForEncode, encoders);

Spring Security 默认使用DelegatingPasswordEncoder

@Bean
public static NoOpPasswordEncoder passwordEncoder() {
    return NoOpPasswordEncoder.getInstance();
}

Spring为防止 跨站请求伪造(CSRF)

CSRF攻击之所以可能是因为受害者网站的HTTP请求与攻击者网站的请求完全相同。这意味着无法拒绝来自邪恶网站的请求并允许来自银行网站的请求。为了防御CSRF攻击,我们需要确保恶意站点无法提供请求中的某些内容,因此我们可以区分这两个请求。
Spring提供了两种机制来防御CSRF攻击:

该解决方案是为了确保每个HTTP请求除了我们的会话cookie外,还必须在HTTP请求中包含一个安全的,随机生成的值,称为CSRF令牌。
提交HTTP请求时,服务器必须查找预期的CSRF令牌,并将其与HTTP请求中的实际CSRF令牌进行比较。如果值不匹配,则应拒绝HTTP请求。
让我们看一下使用同步令牌模式时示例将如何变化。假设实际的CSRF令牌必须位于名为的HTTP参数中_csrf
通常建议将该SameSite属性用作深度防御,而不是针对CSRF攻击的唯一防护。

Servlet应用

Spring Security通过使用标准Servlet与Servlet容器集成Filter。这意味着它可以与在Servlet容器中运行的任何应用程序一起使用。

Servlet安全性:大局

身份验证”,“ 授权”“防止利用漏洞”部分中建立了这种高级理解。

image.png

FilterChain

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    // do something before the rest of the application
    chain.doFilter(request, response); // invoke the rest of the application
    // do something after the rest of the application
}

DelegatingFilterProxy
DelegatingFilterProxy可以通过标准Servlet容器机制进行注册,但是将所有工作委托给实现的Spring Bean Filter。


image.png

另一个好处DelegatingFilterProxy是,它允许延迟查找Filterbean实例。这很重要,因为容器需要Filter在容器启动之前注册实例。但是,Spring通常使用a ContextLoaderListener来加载Spring Bean,直到Filter需要注册实例之后才能完成。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { // Lazily get Filter that was registered as a Spring Bean  // For the example in [DelegatingFilterProxy](https://docs.spring.io/spring-security/site/docs/5.3.2.BUILD-SNAPSHOT/reference/html5/#servlet-delegatingfilterproxy-figure)  `delegate` is an instance of *Bean Filter<sub>0</sub>* Filter delegate = getFilterBean(someBeanName);  // delegate work to the Spring Bean delegate.doFilter(request, response); }

FilterChainProxy


image.png

Spring Security的Servlet支持包含在中FilterChainProxyFilterChainProxyFilterSpring Security提供的一种特殊功能,它允许Filter通过委派许多实例SecurityFilterChain。由于FilterChainProxy是Bean,因此通常将其包装在DelegatingFilterProxy中

SecurityFilterChain
SecurityFilterChainFilterChainProxy用于确定Filter应对此请求调用哪些Spring Security 。

image.png

保安过滤器SecurityFilterChain通常是豆类,但他们与注册FilterChainProxy代替的DelegatingFilterProxyFilterChainProxy直接向Servlet容器或DelegatingFilterProxy注册具有许多优点。首先,它为Spring Security的所有Servlet支持提供了一个起点。因此,如果您想对Spring Security的Servlet支持进行故障排除,则在其中添加调试点FilterChainProxy是一个很好的起点。

其次,由于FilterChainProxy对于Spring Security的使用至关重要,因此它可以执行不被视为可选任务。例如,它清除SecurityContext以避免内存泄漏。它还使用Spring Security HttpFirewall来保护应用程序免受某些类型的攻击。

另外,它在确定何时SecurityFilterChain调用a时提供了更大的灵活性。在Servlet容器中,Filter仅根据URL调用。但是,FilterChainProxy可以HttpServletRequest利用RequestMatcher接口根据任何内容确定调用。

实际上,FilterChainProxy可以用来确定SecurityFilterChain应该使用哪个。如果您的应用程序可以为不同的提供完全独立的配置。

image.png
9.5。安全过滤器

处理安全异常

ExceptionTranslationFilter允许的翻译AccessDeniedExceptionAuthenticationException到HTTP响应。

ExceptionTranslationFilter作为安全过滤器之一插入到FilterChainProxy中。

image.png

| |

如果应用程序未抛出AccessDeniedExceptionAuthenticationExceptionExceptionTranslationFilter则不执行任何操作

ExceptionTranslationFilter伪代码

try {
    filterChain.doFilter(request, response); 
} catch (AccessDeniedException | AuthenticationException e) {
    if (!authenticated || e instanceof AuthenticationException) {
        startAuthentication(); 
    } else {
        accessDenied(); 
    }
}

| | 你可以从召回进展的Filter小号即调用FilterChain.doFilter(request, response)是等效的调用应用程序的其余部分。这意味着如果应用程序的另一部分(即FilterSecurityInterceptor方法安全性)抛出AuthenticationExceptionAccessDeniedException,它将在此处被捕获和处理。 |
| | 如果用户未通过身份验证或为AuthenticationException,则开始身份验证。 |
| | 否则,访问被拒绝 |

上一篇下一篇

猜你喜欢

热点阅读