热门课程

免费试听

上课方式

开班时间

当前位置: 首页 -   文章 -   新闻动态 -   正文

Spring Security快速上手(含代码)

知了堂姐
2024-07-09 11:12:24
0

1、Spring Security介绍

Spring 是一个非常流行和成功的java应用开发框架。

Spring Security 基于Spring 框架,提供了一套web应用安全性的完整解决方案。

Web 应用的安全性包括两部分:

用户认证(Authentication)

用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。

用户授权(Authorization)

用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。

系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。

2、流程说明

3、核心组件

3.1 引入security依赖

  
            org.springframework.security
            spring-security-web
            5.2.4.RELEASE
        
        
            org.springframework.security
            spring-security-config
            5.2.4.RELEASE
        

3.2 Spring容器配置

/**
 * 该配置文件相当于applicationContext.xml文件
 */
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "cn.codewei",excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class)})
public class ApplicationConfig {
    // 在此配置除了Controller的其他bean,比如数据库连接池,事务管理器,业务bean等
}

3.3 ServletContext配置

/**
 * 该配置,就相当于Springmvc.xml文件
 */
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "cn.codewei",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/view/");
        internalResourceViewResolver.setSuffix(".jsp");
        return internalResourceViewResolver;
    }
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login");
    }
}   
 

3.4 加载Spring容器

在init包下定义Spring容器初始化类SpringApplicationInitializer,此类实现WebApplicationInitializer接口,Spring容器启动时加载WebApplicationInitializer接口的所有实现类。

/**
 * 加载Spring容器
 */
public class SpringApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    // spring容器,相当于加载applicationContext.xml
    protected Class[] getRootConfigClasses() {
        return new Class[]{ApplicationConfig.class};
    }
    // servleContext,相当于加载springmvc.xml
    protected Class[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }
    // url-mapping
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

4、认证

4.1 认证页面

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

4.2 安全配置

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

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

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    // 定义用户信息服务(查询用户信息)
    @Override
    @Bean
    protected UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("zhangsan").password("123").authorities("p1").build());
        manager.createUser(User.withUsername("lisi").password("456").authorities("p2").build());
        return manager;
    }
    // 密码编码器
    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();  //NoOpPasswordEncoder 不采用加密算法
    }
    // 配置安全拦截机制
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/r/**").authenticated()  // 所有/r/** 的请求必须认证通过
                .anyRequest().permitAll()  // 其他请求,可以不认证进行访问
                .and()
                .formLogin()  // 允许表单登录
                .successForwardUrl("/login-success");  // 自定义登录成功的页面地址
    }
}

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

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

(1)url匹配/r/**的资源,经过认证后才能访问。

(2)其他url完全开放。

(3)支持form表单认证,认证成功后转向/login-success。

2.加载 WebSecurityConfig

修改SpringApplicationInitializer的getRootConfigClasses()方法,添加WebSecurityConfig.class:

/**
 * 加载Spring容器
 */
public class SpringApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    // spring容器,相当于加载applicationContext.xml
    protected Class[] getRootConfigClasses() {
        return new Class[]{ApplicationConfig.class, WebSecurityConfig.class};
    }
    // servleContext,相当于加载springmvc.xml
    protected Class[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }
    // url-mapping
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

4.3 Spring Security初始化

Spring Security 初始化,这里有两种情况

  • 若当前环境没有使用 Spring或Spring MVC,则需要将 WebSecurityConfig(Spring Security配置类) 传入超类,以确保获取配置,并创建spring context。
  • 相反,若当前环境已经使用 spring,我们应该在现有的springContext中注册Spring Security(上一步已经做将WebSecurityConfig加载至rootcontext),此方法可以什么都不做。

在init包下定义SpringSecurityApplicationInitializer:

public class SpringSecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
    public SpringSecurityApplicationInitializer(){
//        super(WebSecurityConfig.class);
    }
}

4.4 默认根路径请求

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

public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("redirect:/login");
}

spring security默认提供的登录页面。

4.5 认证成功页面

在安全配置中,认证成功将跳转到/login-success,代码如下:

// 配置安全拦截机制
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/r/**").authenticated()  // 所有/r/** 的请求必须认证通过
        .anyRequest().permitAll()  // 其他请求,可以不认证进行访问
        .and()
        .formLogin()  // 允许表单登录
        .successForwardUrl("/login-success");  // 自定义登录成功的页面地址
}

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

在LoginController中定义/login-success:

@RestController
public class LoginController {
    @RequestMapping(value = "/login-success",produces = {"text/html;charset=utf-8"})
    public String loginSuccess(){
        return "登录成功";
    }
}

5、测试

(1) 启动项目,访问http://localhost:8080/路径地址

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

(2) 登录

输入错误的用户名、密码

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

(3) 退出

请求/logout退出

6、授权

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

在LoginController添加/r/r1或/r/r2

/**
* 测试资源
* @return
*/
@GetMapping(value = "/r/r1",produces = "text/plain;charset=utf-8")
public String r1(HttpServletRequest request){
    return "访问资源r1";
}
/**
* 测试资源
* @return
*/
@GetMapping(value = "/r/r2",produces = "text/plain;charset=utf-8")
public String r2(HttpServletRequest request){
    return "访问资源r2";
}

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

.antMatchers("/r/r1").hasAuthority("p1")
.antMatchers("/r/r2").hasAuthority("p2")

.antMatchers(“/r/r1”).hasAuthority(“p1”)表示:访问/r/r1资源的 url需要拥有p1权限

.antMatchers(“/r/r2”).hasAuthority(“p2”)表示:访问/r/r2资源的 url需要拥有p2权限

完整的WebSecurityConfig方法如下:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    // 定义用户信息服务(查询用户信息)
    @Override
    @Bean
    protected UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("zhangsan").password("123").authorities("p1").build());
        manager.createUser(User.withUsername("lisi").password("456").authorities("p2").build());
        return manager;
    }
    // 密码编码器
    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();  //NoOpPasswordEncoder 不采用加密算法
    }
    // 配置安全拦截机制
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/r/r1").hasAuthority("p1")
                .antMatchers("/r/r2").hasAuthority("p2")
                .antMatchers("/r/**").authenticated()  // 所有/r/** 的请求必须认证通过
                .anyRequest().permitAll()  // 其他请求,可以不认证进行访问
                .and()
                .formLogin()  // 允许表单登录
                .successForwardUrl("/login-success");  // 自定义登录成功的页面地址
    }
}
大家都在看

零基础学HTML5前端,零基础前端怎么学?

2024-07-09 浏览次数:0

软件测试常见问题,软件测试工程师需要掌握什么相关...

2024-07-09 浏览次数:0

0基础怎么转行做网络安全?网安怎么学?

2024-07-09 浏览次数:0

2022,前端就业现状怎么样?

2024-07-09 浏览次数:0

想当程序员,成都哪家it培训机构哪家比较靠谱?有...

2024-07-09 浏览次数:0

Web前端是自学好,还是去培训机构,市场饱和了吗...

2024-07-09 浏览次数:0
最新资讯
Java里的ioc技术怎么用?... spring技术可以说是java企业开发里最重要的技术,而spring这么大的框都是建立在ioc和a...
SpringBoot整合富文本... SpringBoot整合富文本编辑器
SpringBoot整合Dru... 1、Druid简介 Druid是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数...
SpringBoot整合QQ邮... 前言 邮件服务是我们工作中常用的服务之一,作用是非常的多,对外可以给用户发送活动、营销广告等;对内可...
MybatisPlus介绍以及... MybatisPlus在Mybatis的基础上只做增强,不做改变,就像是魂斗罗中的红人和蓝人一样。 ...
SpringBoot 整合 E... Elasticsearch可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司...
SpringBoot整合Cap... 1. 基本结构 使用Captcha生成验证码, 利用Redis存储验证码; Redis中的结构为...
Spring Security... 1、Spring Security介绍 Spring 是一个非常流行和成功的java应用开发框...