spring security

阅读数:210 评论数:0

跳转到新版页面

分类

python/Java

正文

一、概述

SpringSecurity中认证(Authentication)和授权(Authorization)是分开的,认证是判断一个用户是否为合法用户,授权是访问控制。

在SpringSecurity中,认证和授权都是基于过滤器完成的。

默认过滤器并不是直接放在 Web 项目的原生过滤器链中,而是通过一个
FlterChainProxy 来统一管理。

二、AuthenticationManager

public interface AuthenticationManager { 
    // 返回Authentication表示认证成功,抛出异常,表示失败
    Authentication authenticate(Authentication authentication)throws AuthenticationException;
}

AuthenticationManager 主要实现类为 ProviderManager,在 ProviderManager 中管理了众多 AuthenticationProvider 实例。

在一次完整的认证流程中,Spring Security 允许存在多个 AuthenticationProvider ,用来实现多种认证方式,这些 AuthenticationProvider 都是由 ProviderManager 进行统一管理的。

三、Authentication

认证以及认证成功的信息主要是由 Authentication 的实现类进行保存的

public interface Authentication extends Principal, Serializable {
        // 获取用户权限信息
	Collection<? extends GrantedAuthority> getAuthorities();
        // 获取用户凭证信息,一般指密码
	Object getCredentials();
        // 获取用户详细信息
	Object getDetails();
        // 获取用户身份信息,用户名、用户对象等
	Object getPrincipal();
        // 用户是否认证成功
	boolean isAuthenticated();
	void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}

四、SecurityContextHolder

SecurityContextHolder 用来获取登录之后用户信息。

Spring Security 会将登录用户数据保存在 Session 中。

SecurityContextHolder有三种工作模式

MODE_THREADLOCAL(默认) 使用ThreadLocal保存信息,此方式也是非常适合Servlet web应用,因为对于一个请求的处理,不管经历了多少Filter,都是在一个线程中进行的。但是对于不同的servlet request,使用的线程不一定是同一个线程
MODE_GLOBAL 数据保存在一个静态变量中,其存储载体是一个静态变量,可以在多线程环境下使用,但是用的比较少。
MODE_INHERITABLETHREADLOCAL 其存储载体为InheritableThreadLocal,InheritableThreadLocal继承ThreadLocal,多了一个特性,就是在创建子进程的时候,会自动的将父进程中的数据复制到子进程中去,实现了子进程能够获取父进程数据的功能。
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication()
UserDetails principal = (UserDetails)authentication.getPrincipal();

五、AccessDecisionManager

访问决策管理器,用来决定此次访问是否被允许。

六、AccessDecisionVoter

访问决定投票器。

AccesDecisionVoter 和 AccessDecisionManager 都有众多的实现类,在 AccessDecisionManager 中会换个遍历 AccessDecisionVoter,进而决定是否允许用户访问,因而 AccesDecisionVoter 和 AccessDecisionManager 两者的关系类似于 AuthenticationProvider 和 ProviderManager 的关系。

七、ConfigAttribute

用来保存授权时的角色信息。

在 Spring Security 中,用户请求一个资源(通常是一个接口或者一个 Java 方法)需要的角色会被封装成一个 ConfigAttribute 对象,在 ConfigAttribute 中只有一个 getAttribute方法,该方法返回一个 String 字符串,就是角色的名称。

八、Spring Security提供的过滤器

默认情况下Spring Boot 在对 Spring Security 进入自动化配置时,会创建一个名为 SpringSecurityFilerChain 的过滤器,并注入到 Spring 容器中

名称 作用 默认是否加载
ChannelProcessingFilter 过滤请求协议 HTTP 、HTTPS NO
CorsFilter 处理跨域问题 NO
OAuth2AuthorizationRequestRedirectFilter 处理 OAuth2 认证重定向 NO
X509AuthenticationFilter 处理 X509 认证 NO

Saml2WebSsoAuthenticationRequestFilter

Saml2WebSsoAuthenticationFilter

处理 SAML 认证 NO
AbstractPreAuthenticatedProcessingFilter 处理预认证问题 NO
CasAuthenticationFilter 处理 CAS 单点登录 NO
OAuth2LoginAuthenticationFilter 处理 OAuth2 认证 NO
BearerTokenAuthenticationFilter 处理 OAuth2 认证的 Access Token NO
OAuth2AuthorizationCodeGrantFilter 处理OAuth2认证中授权码 NO
OpenIDAuthenticationFilter 处理 OpenID 认证 NO
ConcurrentSessionFilter 处理 Session 有效期 NO
DigestAuthenticationFilter 处理 HTTP 摘要认证 NO
JaasApiIntegrationFilter 处理 JAAS 认证 NO
RememberMeAuthenticationFilter 处理 RememberMe 登录 NO
SwitchUserFilter 处理账户切换 NO
WebAsyncManagerIntegrationFilter 将 WebAsyncManger 与 SpringSecurity 上下文进行集成 YES
SecurityContextPersistenceFilter 在处理请求之前,将安全信息加载到 SecurityContextHolder 中 YES
HeaderWriterFilter 处理头信息加入响应中 YES
CsrfFilter 处理 CSRF 攻击 YES
LogoutFilter 处理注销登录 YES
UsernamePasswordAuthenticationFilter 处理表单登录 YES
DefaultLoginPageGeneratingFilter 配置默认登录页面 YES
DefaultLogoutPageGeneratingFilter 配置默认注销页面 YES
BasicAuthenticationFilter 处理 HttpBasic 登录 YES
RequestCacheAwareFilter 处理请求缓存 YES
AwareRequestFilter 包装原始请求 YES
AnonymousAuthenticationFilter 配置匿名认证 YES
SessionManagementFilter 处理 session 并发问题 YES
ExceptionTranslationFilter 处理认证/授权中的异常 YES
FilterSecurityInterceptor 处理授权相关 YES

九、SpringBoot security auto configuration

1、默认的安装设置

为spring boot添加安全配置,只需要添加如下依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

这会包含SecurityAutoConfiguration类,这包含初始化和默认的安全配置。

有一些预定义的属性:

spring.security.user.name
spring.security.user.password

如果不指定密码,那么会生成一个随机密码,在console输出中可以看到:

Using default security password: c8be15de-4488-4490-9dc6-fab3f91435c6

2、关闭Auto-Configuration

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class SpringBootSecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootSecurityApplication.class, args);
    }
}

或者在配置文件中添加

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration

3、SpringBootWebSecurityConfiguration

@Configuration(proxyBeanMethods = false)
@ConditionalOnDefaultWebSecurity
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {
	@Bean
	@Order(SecurityProperties.BASIC_AUTH_ORDER)
	SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) 
    throws Exception {
			http.authorizeRequests().anyRequest()
      .authenticated().and().formLogin().and().httpBasic();
		return http.build();
	}
}

默认的生效条件:

class DefaultWebSecurityCondition extends AllNestedConditions {

	DefaultWebSecurityCondition() {
		super(ConfigurationPhase.REGISTER_BEAN);
	}

	@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
	static class Classes {

	}

	@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
	static class Beans {

	}

}

(1)条件一 classpath中存在 SecurityFilterChain.class, HttpSecurity.class

(2)条件二 没有自定义 WebSecurityConfigurerAdapter.class, SecurityFilterChain.class

十、WebSecurityConfigurerAdapter

WebSecurityConfigurerAdapter 这个类极其重要,它扩展 Spring Security 所有默认配置。

如果要对 Spring Security 进行自定义配置,就要自定义这个类实例,通过覆盖类中方法达到修改默认配置的目的。

@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
         http.authorizeHttpRequests()
                .mvcMatchers("/login.html").permitAll()
                .mvcMatchers("/index").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/doLogin")
                .usernameParameter("uname")
                .passwordParameter("passwd")
                .successForwardUrl("/index") 		 //forward 跳转           注意:不会跳转到之前请求路径
                //.defaultSuccessUrl("/index")   //redirect 重定向    注意:如果之前请求路径,会有优先跳转之前请求路径
                .failureUrl("/login.html")
                .and()
                .csrf().disable();//这里先关闭 CSRF
    }
}
permitAll()
代表放行该资源,该资源为公共资源 无需认证和授权可以直接访问
注意: 放行资源必须放在所有认证请求之前!
anyRequest().authenticated()
代表所有请求,必须认证之后才能访问
formLogin()
代表开启表单认证
successForwardUrl 默认使用 forward 跳转 注意:不会跳转到之前请求路径
defaultSuccessUrl 默认使用 redirect 跳转 注意:如果之前请求路径,会有优先跳转之前请求路径,可以传入第二个参数进行修改

十一、UserDetailService

用来修改默认认证的数据源信息。

public interface UserDetailsService {
	UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

默认情况下都会满足,此时Spring Security会提供一个 InMemoryUserDetailManager 实例

 




相关推荐

一、request uri部分 @PathVariable 获取路径参数,形如url/{id} 二、request header部分 @RequestHeade

一、概述 一个项目使用多个数据库(无论是主从复制--读写分离还是分布式数据库结构)的重要性变得越来越明显,整合的多数据源有两种方式:分包和aop。 1、SqlSessionTemplate SqlSe

一、概述 PageHelper是开源免费的mybatis第三方分页插件。 二、使用 1、pom引入 <dependency> <groupId>com.github.pageh

一、日志框架的介绍 Spring Boot 2.*默认采用slf4j+logback的形式,slf4j是个通用的日志门面,logback就是个具体的日志框架了。

一、问题解决方式 @PostMapping("/insert") @ResponseBody private ResultVO insert1(@RequestParam Map<String, St

JJWT 全称Java Json Web Token。 而JWT是一种在两方之间传输信息的方法,在jwt的主体中编码的信息被称为claims。jwt的扩展形式是json,因此每个c

POM依赖 &lt;dependency&gt; &lt;groupId&g

一、概述 @EnableConfigurationProperties注解的作用是:让使用了@ConfigurationProperties注解的类生效,并且将该类注入到IOC容器中,交由IOC容器进

一、概述 Druid(德鲁伊)是Java语言中的数据库连接池,Spring Boot 2.x默认使用Hikari数据源,虽然HikariCP的速度稍快,但是,Druid能够提供强大的监控和扩展功能。

1、配置文件的格式 springboot可以识别两种格式的配置文件,分别是yml文件与properties文件,我们可以将application.properties文件换成a