首页 > 编程语言 > 详细

Spring Security

时间:2020-05-27 22:18:07      阅读:46      评论:0      收藏:0      [点我收藏+]

Spring Security教程

1.介绍

Spring Security is a powerful and highly customizable authentication and access-control framework.

Spring Security是一个功能强大并且高度可定制认证和授权框架.

1.1 特点

  • Authentication:认证,用户登录的验证(解决你是谁的问题)
  • Authorization:授权,用户对于服务器资源访问的权限(解决你能干什么的问题)
  • 安全防护,防止攻击:例如session攻击,点击劫持,跨站点请求伪造等

1.2 与Shiro对比

Shiro也是一个支持认证和授权的框架

1.使用方便度(Shiro)

  • shiro入门更加容易,使用起来也非常简单,这也是造成shiro的使用量一直高于Spring Security的主要原因
  • 在没有Spring Boot之前,Spring Security的大部分配置要通过XML实现,配置还是还是非常复杂的。但是有了 Spring Boot之后,这一情况已经得到显著改善

2.功能丰富性(Security)

  • Spring Security默认含有对OAuth2.0的支持,与Spring Social一起使用完成社交媒体登录也比较方便。shiro在这方面只能靠自己写代码实现。

3.总结

对于简单的Web应用,使用Shiro更加的轻量;对于分布式、微服务或者SpringCloud系列深度集成的项目使用Spring Security,因为它是Spring的亲儿子

1.3 SpringBoot 整合

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

2.HttpBasic模式

HttpBasic登录验证模式是Spring Security实现登录验证最简单的一种方式不能进行定制登录页面,而是弹出一个Security提供的登录框进行认证,它是一种"防君子不防小人"的验证模式,可以通过劫持请求获取请求头Authorization解码破解获取用户名和密码,适合数据不是很敏感的场景

2.1 HttpBasic认证

如果使用的Spring Boot版本为1.X版本,依赖的Security 4.X版本,那么就无需任何配置,启动项目访问则会弹出默认的httpbasic认证.

spring boot2.0版本(依赖Security 5.X版本),HttpBasic不再是默认的验证模式,在spring security 5.x默认的验证模式已经是表单模式。所以我们要使用Basic模式,需要自己调整一下。并且security.basic.enabled已经过时了,所以我们需要自己去编码实现。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic() //开启httpBasic模式认证
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated(); //所有请求都需要认证才能访问
    }
}

启动程序,控制台会有一串base64,用于验证的密码

Using generated security password: 5bbe11f1-f011-4317-9910-5736086dcbaa

浏览器访问localhost:8080,会弹出授权框填写用户名密码授权就会进入主页,用户名默认为user,密码就上控制台的密码
技术分享图片

也可以自定义用户名密码,在application.yml中

spring:
	security:
		user:
			name: admin
			password: 123456

2.2 HttpBasic原理

  • 浏览器访问服务器资源,服务器需要浏览器发送用户名和密码验证
  • 浏览器将用户名和密码通过base64编码放在请求头Authorization中发送给服务器,格式为Basic+空格+base64
  • 服务器收到请求后会提取请求头Authorization的值并对base64解码,然后进行对比用户名和密码,一致则通过

知道了它的原理以后,就知道为什么不安全了,如果对http的Header进行劫持的话,然后获取到Authorization的信息进行Base64解码就可以得到用户名和密码

3.formLogin模式

fromLogin模式相比于httpBasic模式更常用,它支持定制化登录页面,而且提供多种登录模式

3.1 formLogin认证

formLogin模式认证总结需要四个要素:

  • 登录认证逻辑(登录页、登录请求的url、登录成功后请求的url)
  • 资源权限访问控制(对页面以及url进行权限控制),对于权限的控制有角色和权限ID两种方式
  • 用户信息及角色和权限ID的分配设置
  • 对静态资源进行忽略,开放静态资源不需要认证

3.2 登录认证及资源权限控制

首先,创建一个类继承WebSecurityAdapter,然后重写config(HttpSecurity http)方法,然后进行配置登陆认证逻辑和资源访问权限的控制

//登陆认证和权限控制
@Override
protected void configure(HttpSecurity http) throws Exception {
  
        http.csrf().disable()//关闭跨站csrf攻击防御,不然访问不了
             .formLogin() //开启formLogin模式认证
                //登录认证逻辑(静态)
                .loginPage("/login.html")   //登录页面
                .loginProcessingUrl("/login") //登录请求哪个url
                .defaultSuccessUrl("/index")  //登录成功后请求哪个url
                .usernameParameter("uname") //默认是username,与前端中的name保持一致
                .passwordParameter("pword") //默认是password,与前端中的name保持一致
             .and()
                //资源权限访问控制(动态)
                .authorizeRequests()
                .antMatchers("/login.html", "/login").permitAll() //不需要认证就可以访问的页面和url
                .antMatchers("/biz1", "/biz2").hasAnyAuthority("ROLE_user", "ROLE_admin") //需要user或者admin权限才能访问
                .antMatchers("/sysuser", "/syslog").hasAnyRole("admin")  //需要admin权限才能访问
//                .antMatchers("/syslog").hasAuthority("sys:log")
//                .antMatchers("/sysuser").hasAuthority("sys:user")
                 //除了上面设置过的请求 ,其余任何请求都需要授权认证
                .anyRequest().authenticated();
  
}

对于上面代码的解析,主要分为两部分:

  • 第一部分是formLogin()配置,用于配置登陆认证逻辑相关的信息,如:登陆页面、登录请求的url等
  • 第二部分是authorizeRequests()配置,用于配置资源访问权限的控制信息,如:登录相关的资源permitAll全部开放无需认证,对于"biz1"、"biz2"需要user或者admin权限才可以访问,对于"/sysuser"、"/syslog"需要admin权限才可以访问,对于其它请求必须通过登录认证才可以访问
  • antMatchers()代表匹配的资源
  • permitAll()代表无需认证就可以访问
  • hasAnyAuthority()hasAnyRole()作用一致,代表需要某个角色才可以访问,不同的是hasAnyAuthority()的格式为 "ROLE_角色名",需要 "ROLE"前缀,而hasAnyRole()只需要写角色名
  • hashAuthority()配置的是权限ID,代表需要具备某个权限才可以访问
  • anyRequest().authenticated();代表其余请求都需要授权认证才可访问,没有权限也可以

3.3 用户信息及角色权限分配设置

当配置好了登录认证逻辑和资源访问控制规则,还需要配置具体的用户和用户的角色,这样才能针对用户进行控制,重写WebSecurityConfigurerAdapter的config(AuthenticationManagerBuilder auth)方法

//用户和角色配置
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication() //在内存中存储用户的身份认证和授权信息
                .withUser("user") //用户名
                .password(passwordEncoder().encode("123456")) //密码
                .roles("user") //分配user角色
//              .authorities("sys:user")
               .and()
                .withUser("admin") //用户名
                .password(passwordEncoder().encode("123456")) //密码
                .roles("admin") //分配admin角色
//              .authorities("sys:log")
               .and()
                .passwordEncoder(passwordEncoder());//配置BCrypt加密
}

//密码加密处理
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

对于上面代码的解析:

  • inMemoryAuthentication():在内存中存储用户的身份认证和授权信息
  • withUser("user")用户名是user
  • password(passwordEncoder().encode("123456"))密码是加密后的123456
  • roles("user")角色是user,可以访问上面规则中只有具有user角色才可以访问的资源,可以配置多个角色,以 "," 分割
  • authorities("sys:user")权限ID是sys:user,可以访问上面规则中只有具有sys:user才可以访问的资源,可以配置多个权限ID,以 "," 分割
  • passwordEncoder(passwordEncoder())配置密码用BCrypt加密

3.4 忽略静态资源

在开发中,不仅要对login相关的资源进行无条件的访问,还需要对静态资源,比如css、js、img、swagger等资源进行开放,不需要只有通过授权才可以访问,不然我们的资源就加载不出来,重写configure(WebSecurity web)方法

//忽略静态资源,将静态资源开放,不需要认证
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring()
            .antMatchers("/css/**","/js/**","/image/**","/fonts/**");
}

这段代码很好理解,只需要对静态资源进行配置就可以忽略了

4.原理

Spring Security基本都是通过过滤器来完成身份认证、权限控制,核心就是过滤器链

技术分享图片

对上图进行解析:

Spring Security

原文:https://www.cnblogs.com/dingjn/p/12976726.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!