Spring Security is a powerful and highly customizable authentication and access-control framework.
Spring Security是一个
功能强大并且高度可定制
的认证和授权
框架.
Shiro也是一个支持认证和授权的框架
1.使用方便度(Shiro)
2.功能丰富性(Security)
3.总结
对于简单的Web应用,使用Shiro更加的轻量;对于分布式、微服务或者SpringCloud系列深度集成的项目使用Spring Security,因为它是Spring的亲儿子
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
HttpBasic登录验证模式是Spring Security实现登录验证最简单的一种方式,不能进行定制登录页面,而是弹出一个Security提供的登录框进行认证,它是一种"防君子不防小人"的验证模式,可以通过劫持请求获取请求头Authorization解码破解获取用户名和密码,适合数据不是很敏感的场景
如果使用的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
知道了它的原理以后,就知道为什么不安全了,如果对http的Header进行劫持的话,然后获取到Authorization的信息进行Base64解码就可以得到用户名和密码
fromLogin模式相比于httpBasic模式更常用,它支持定制化登录页面,而且提供多种登录模式
formLogin模式认证总结需要四个要素:
角色和权限ID两种方式
首先,创建一个类继承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();
代表其余请求都需要授权认证才可访问,没有权限也可以当配置好了登录认证逻辑和资源访问控制规则,还需要配置具体的用户和用户的角色,这样才能针对用户进行控制,重写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")
用户名是userpassword(passwordEncoder().encode("123456"))
密码是加密后的123456roles("user")
角色是user,可以访问上面规则中只有具有user角色才可以访问的资源,可以配置多个角色,以 "," 分割authorities("sys:user")
权限ID是sys:user,可以访问上面规则中只有具有sys:user才可以访问的资源,可以配置多个权限ID,以 "," 分割passwordEncoder(passwordEncoder())
配置密码用BCrypt加密在开发中,不仅要对login相关的资源进行无条件的访问,还需要对静态资源,比如css、js、img、swagger等资源进行开放,不需要只有通过授权才可以访问,不然我们的资源就加载不出来,重写configure(WebSecurity web)
方法
//忽略静态资源,将静态资源开放,不需要认证
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/css/**","/js/**","/image/**","/fonts/**");
}
这段代码很好理解,只需要对静态资源进行配置就可以忽略了
Spring Security基本都是通过
过滤器
来完成身份认证、权限控制,核心就是过滤器链
对上图进行解析:
原文:https://www.cnblogs.com/dingjn/p/12976726.html