Spring整合SpringSecurity(一)

  • 创建项目
  • 创建maven工程
  • Spring容器注解配置
  • Servlet Context注解配置
  • 加载 Spring容器
  • 认证
  • 认证页面
  • 安全配置
  • Spring Security初始化
  • 默认根路径请求
  • 认证成功页面
  • 测试
  • 登录测试
  • 退出
  • 授权
  • HttpSecurity


创建项目

代码远程地址:https://github.com/zysheep/spring-security.git

创建maven工程

spring actuator结合security spring整合security_HTTP


spring actuator结合security spring整合security_HTTP_02

项目结构:

spring actuator结合security spring整合security_spring_03

添加pom依赖

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.8</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>5.4.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>5.4.5</version>
        </dependency>
    </dependencies>

Spring容器注解配置

相当于配置文件application-context.xml

@Configuration
@ComponentScan(basePackages = "cn.zysheep",
        excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class)})
public class ApplicationConfig {
    //在此配置除了Controller的其它bean,比如:数据库链接池、事务管理器、业务bean等。
}

Servlet Context注解配置

相当于spring- mvc.xml配置文件

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "cn.zysheep",
        includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class)})
public class WebConfig implements WebMvcConfigurer {

    // 配置视图解析器
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
        internalResourceViewResolver.setPrefix("/WEB-INF/views/");
        internalResourceViewResolver.setSuffix(".jsp");
        return internalResourceViewResolver;
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addRedirectViewController("/","/login");
    }
}

加载 Spring容器

相当于web.xml配置

public class SpringApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{ApplicationConfig.class, WebSecurityConfig.class}; //指定spring容器
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class}; // 指定servletConfig即springmvc配置
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

认证

认证页面

springSecurity默认提供认证页面,不需要额外开发。

spring actuator结合security spring整合security_spring_04

安全配置

spring security提供了用户名密码登录、退出、会话管理等认证功能,只需要配置即可使用。

在config包下定义WebSecurityConfig,安全配置的内容包括:用户信息、密码编码器、安全拦截机制。

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager detailsManager = new InMemoryUserDetailsManager();
        detailsManager.createUser(User.withUsername("zhangsan").password("123").authorities("save","update").build());
        detailsManager.createUser(User.withUsername("lisi").password("456").authorities("save").build());

        return detailsManager;
    }

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

    //配置授权服务,即安全拦截机制
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/user/**").authenticated()
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .successForwardUrl("/user/login-success");
    }
}

在userDetailsService()方法中,我们返回了一个UserDetailsService给spring容器,Spring Security会使用它来 获取用户信息。我们暂时使用InMemoryUserDetailsManager实现类,并在其中分别创建了zhangsan、lisi两个用 户,并设置密码和权限

而在configure()中,我们通过HttpSecurity设置了安全拦截规则,其中包含了以下内容:

  • 关闭csrf
  • url匹配/user/**的资源,经过认证后才能访问。
  • 其他url完全开放。
  • 支持form表单认证,认证成功后转向/login-success。

加载 WebSecurityConfig

@Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{ApplicationConfig.class, WebSecurityConfig.class}; //指定spring容器,加载WebSecurityConfig
    }

Spring Security初始化

public class SpringSecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

}

默认根路径请求

在WebConfig.java中添加默认请求根路径跳转到/login,此url为spring security提供:

//默认Url根路径跳转到/login,此url为spring security提供
@Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addRedirectViewController("/","/login");
    }

认证成功页面

在安全配置中,认证成功将跳转到/login-success,还可以配置登录页面和登录请求,认证失败请求

spring actuator结合security spring整合security_ide_05

//配置授权服务,即安全拦截机制
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/user/**").authenticated()
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .successForwardUrl("/user/login-success");
    }

spring security支持form表单认证,认证成功后转向/login-success。

在LoginController中定义/login-success:

@Controller
@RequestMapping("/user")
public class LoginController {

    @PostMapping("/login-success")
    public String loginSuccess() {
    	//跳转到success页面
        return "success";
    }
}

spring actuator结合security spring整合security_HTTP_06

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功页面</title>
</head>
<body>
<h1>登录成功</h1>
</body>
</html>

测试

配置Tomcat,启动项目

spring actuator结合security spring整合security_spring_07


页面会根据WebConfig中addViewControllers配置规则,跳转至/login,/login是spring Security提供的默认登录页面。

登录测试

输入错误的用户名、密码

spring actuator结合security spring整合security_spring_08


http://localhost:8080/login?error时spring security默认为我们提供的错误认证请求

输入正确的用户名、密码,登录成功

spring actuator结合security spring整合security_spring_09


spring security内部转发到了/user/login-success请求,我们自定义了这请求响应一个视图页面sucess.jsp

退出

请求/logout退出

spring actuator结合security spring整合security_HTTP_10


/logout请求是SpringSecurity为我们提供的,退出 后再访问资源自动跳转到登录页面

授权

实现授权需要对用户的访问进行拦截校验,校验用户的权限是否可以操作指定的资源,Spring Security默认提供授 权实现方法。

LoginController添加资源请求

@Controller
@RequestMapping("/user")
public class LoginController {

    @PostMapping("/login-success")
    public String loginSuccess() {
        return "success";
    }


    @GetMapping("/save")
    @ResponseBody
    public String saveUser() {
        return "save resources";
    }

    @GetMapping("/update")
    @ResponseBody
    public String updateUser() {
        return "update resources";
    }

    @GetMapping("/delete")
    @ResponseBody
    public String deleteUser() {
        return "delete resources";
    }

    @GetMapping("/get")
    @ResponseBody
    public String getUser() {
        return "get resources";
    }

}

在安全配置类WebSecurityConfig.java中配置授权规则:

.antMatchers("/user/save").hasAuthority("save")
 .antMatchers("/user/update").hasAuthority("update")

.antMatchers("/user/save").hasAuthority("save")表示:访问/user/save资源的 url需要拥有save权限。

.antMatchers("/user/update").hasAuthority("update")表示:访问/user/save资源的 url需要拥有update权限。

完整的WebSecurityConfig方法如下:

//配置授权服务,即安全拦截机制
@Override
protected void configure(HttpSecurity http) throws Exception {
   http.csrf().disable()
      .authorizeRequests()
      .antMatchers("/user/save").hasAuthority("save")
      .antMatchers("/user/update").hasAuthority("update")
      .antMatchers("/user/**").authenticated()
      .anyRequest().permitAll()
      .and()
      .formLogin()  // 支持form表单验证
      .successForwardUrl("/user/login-success"); // 自定义登录成功请求
}

测试:

  1. 先使用内存用户,登录成功
  2. 内存用户zhansan具有save和update访问权限,lisi具有save权限
  3. spring actuator结合security spring整合security_spring_11

  4. 访问/user/save和/user/update,有权限时则正常访问,否则返回403(拒绝访问)
  5. spring actuator结合security spring整合security_HTTP_12

  6. zhansan和lisi都可以访问/user/get和/user/delete资源,spring security对所有资源进行认证,认证用户即成功登录用户,/user/get和/user/delete都允许认证用户访问

HttpSecurity

HttpSecurity配置列表:

方法

说明

openidLogin()

用于基于 OpenId 的验证

headers()

将安全标头添加到响应

cors()

配置跨域资源共享( CORS )

sessionManagement()

允许配置会话管理

portMapper()

允许配置一个PortMapper(HttpSecurity#(getSharedObject(class))),其他提供SecurityConfigurer的对象使用 PortMapper 从 HTTP 重定 向到 HTTPS 或者从 HTTPS 重定向到 HTTP。默认情况下,Spring Security使用一个PortMapperImpl映射 HTTP 端口8080到 HTTPS 端口 8443,HTTP 端口80到 HTTPS 端口443

jee()

配置基于容器的预认证。 在这种情况下,认证由Servlet容器管理

x509()

配置基于x509的认证

rememberMe

允许配置“记住我”的验证

authorizeRequests()

允许基于使用HttpServletRequest限制访问

requestCache()

允许配置请求缓存 exceptionHandling() 允许配置错误处理

securityContext()

在HttpServletRequests之间的SecurityContextHolder上设置SecurityContext的管理。 当使用WebSecurityConfigurerAdapter时,这将 自动应用

servletApi()

将HttpServletRequest方法与在其上找到的值集成到SecurityContext中。 当使用WebSecurityConfigurerAdapter时,这将自动应用

csrf()

添加 CSRF 支持,使用WebSecurityConfigurerAdapter时,默认启用

logout()

添加退出登录支持。当使用WebSecurityConfigurerAdapter时,这将自动应用。默认情况是,访问URL”/ logout”,使HTTP Session无效来 清除用户,清除已配置的任何#rememberMe()身份验证,清除SecurityContextHolder,然后重定向到”/login?success”

anonymous()

允许配置匿名用户的表示方法。 当与WebSecurityConfigurerAdapter结合使用时,这将自动应用。 默认情况下,匿名用户将使用 org.springframework.security.authentication.AnonymousAuthenticationToken表示,并包含角色 “ROLE_ANONYMOUS”

formLogin()

指定支持基于表单的身份验证。如果未指定FormLoginConfigurer#loginPage(String),则将生成默认登录页面

oauth2Login()

根据外部OAuth 2.0或OpenID Connect 1.0提供程序配置身份验证

requiresChannel()

配置通道安全。为了使该配置有用,必须提供至少一个到所需信道的映射

httpBasic()

配置 Http Basic 验证

addFilterAt()

在指定的Filter类的位置添加过滤器