Spring学习日志之Spring Security配置

依赖引入

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

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

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

启用Spring Security

  • 首先创建一个继承AbstractSecurityWebApplicationInitializer的类。这个操作会导致一个名为DelegatingFilterProxyFilter被注册,它会拦截发往应用中的请求,并将请求委托给ID为SpringSecurityFilterChain的bean
public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer
{
}
  • 再创建一个配置类
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
}

至此Spring Security就被启用了,目前所有的请求都会被拦截

配置

WebSecurityConfigurerAdapter中有三个名为configure的方法提供重载,三个方法的描述如下:

方法 描述
configure(HttpSecurity) 配置拦截模式
configure(AuthenticationManagerBuilder) 配置用户信息
configure(WebSecurity) 配置Spring Security的Filter链

配置用户信息

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.inMemoryAuthentication()   // 基于内存的用户存储
            .withUser("admin")
            .password("password")
            .roles("USER", "ADMIN");
    }

配置拦截路径

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
                .antMatchers("/info").authenticated()
                .antMatchers(HttpMethod.GET, "/health").hasAnyAuthority("ADMIN")
                .anyRequest().permitAll();
    }
}

启用HTTPS

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
                .anyRequest().permitAll()
                .and()
                .requiresChannel()
                .antMatchers("/bankInfo").requiresSecure()  // enable HTTPS
                .antMatchers("/").requiresInsecure();       // disable HTTPS
    }
}

禁用CSRF

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
                .anyRequest().permitAll()
                .and()
                .csrf().disable();
    }
}

登录与注销

  • 在重写configure(HttpSecurity)之前会有一个默认的登录页面,需要登录时会自动跳转到这个位于/login下的页面,但一旦重写此方法后就会失去这个简单的登录页面。

启用默认登录页

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
                .anyRequest().permitAll()
                .and()
                .formLogin();
    }
}

自定义登录页面

如果不想做多余的配置,那么自定义的页面里:

  • formaction应该提交到/login
  • 包含username的输入域且name属性为username
  • 包含password的输入域且name属性为password

指定URL

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
                .anyRequest().permitAll()
                .and()
                .formLogin().loginPage("/login");
    }
}

指定自定义页面

@Configuration
@EnableWebMvc
@ComponentScan
public class WebConfig extends WebMvcConfigurerAdapter {
   @Override
   public void addViewControllers(ViewControllerRegistry registry) {
      registry.addViewController("/login").setViewName("login");
   }
}

ViewControllerRegistry可以用来直接转发请求到一个视图而无需编写控制器类。

注销

  • 如果没有启用CSRF,直接访问\logout就可实现登出
  • 如果启用CSRF,用POST方法访问\logout并带上CSRF Token
posted @ 2018-01-22 23:59  Decouple  阅读(4058)  评论(0编辑  收藏  举报