一:什么是Spring Security
Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。提供了完善的认证机制和方法级的授权功能。是一款非常优秀的权限管理框架。它的核心是一组过滤器链,不同的功能经由不同的过滤器。
二:认证授权功能实现
1,准备一个springCloud的工程,引入oAuth2的依赖
<!-- oAuth2 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
2,创建基于内存的认证/授权配置类
@EnableWebSecurity
@Configuration
public class webSecurityConfig extends WebSecurityConfigurerAdapter {
//密码编译比对方式
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
//访问路径配置
@Override
protected void configure(HttpSecurity http) throws java.lang.Exception {
//.hasAuthority : 基于资源授权 .hasRole:基于角色授权
http.authorizeRequests()
.antMatchers("/auth/hello").hasRole("GUEST") //给访问的地址加上角色限制,只有指定的角色才能访问
.antMatchers("/auth/home").hasRole("USER")
.antMatchers("/auth/admin").hasRole("ADMIN")
.antMatchers("/test/health").permitAll() //此路径不需要经过过认证,可以不登录直接请求
.anyRequest().authenticated() //除配置的/test/health路径其他请求都需要认证
.and()
.formLogin() //允许表单登陆
.successForwardUrl("/sys/login"); //自定义表单登陆成功后的跳转路径
}
//基于内存的用户配置
@Override
protected void configure(AuthenticationManagerBuilder auth) throws java.lang.Exception {
//创建三个用户到内存中,并给他们分配角色
auth.inMemoryAuthentication()
.withUser("zhangsan").password(this.passwordEncoder().encode("123456")).roles("GUEST");
auth.inMemoryAuthentication()
.withUser("lisi").password(this.passwordEncoder().encode("123456")).roles("USER");
auth.inMemoryAuthentication()
.withUser("wangwu").password(this.passwordEncoder().encode("123456")).roles("USER","ADMIN");
}
}
要访问测试的接口
@GetMapping("/auth/hello")
@ResponseBody
public String test1(){
logger.info("+++++++++++++++++++++++++++++++请求成功TEST_GUEST+++++++++++++++++++++++++++++++++++");
return "GUEST";
}
@GetMapping("/auth/home")
@ResponseBody
public String test2(){
logger.info("+++++++++++++++++++++++++++++++请求成功TEST_USER+++++++++++++++++++++++++++++++++++");
return "USER";
}
@GetMapping("/auth/admin")
@ResponseBody
public String test3(){
logger.info("+++++++++++++++++++++++++++++++请求成功TEST_ADMIN+++++++++++++++++++++++++++++++++++");
return "ADMIN";
}
@RequestMapping("/sys/login")
@ResponseBody
public String test4(){
logger.info("+++++++++++++++++++++++++++++++请求成功TEST_SYS_LOGIN+++++++++++++++++++++++++++++++++++");
return "登陆成功TESDT";
}
@GetMapping("/test/health")
@ResponseBody
public String test5(){
logger.info("+++++++++++++++++++++++++++++++—健康检查—TEST+++++++++++++++++++++++++++++++++++");
return "健康检查";
}
3,启动项目,并访问 http://localhost:9901/login (不唯一) ,出现登陆页面就说明该工程具备oAuth2的功能了

三:测试:
场景一:登陆zhangsan(角色:GUEST),然后访问 /auth/hello 路径(该路径配置的角色:GUEST),人物角色和路径角色一致,那么能调通测试接口
步骤一:登陆:

步骤二:登陆成功,返回自定义接口内容

步骤三:访问 /auth/hello 的接口,浏览器输入 http://localhost:9901/auth/hello 得到了接口返回的字符串

场景二:登陆zhangsan(角色:GUEST),然后访问 /auth/admin 路径(该路径配置的角色:ADMIN),人物角色和路径角色不一致,那么不能调通测试接口
步骤一:场景一zhangsan已经登陆这里直接访问 http://localhost:9901/auth/admin
,由于该路径没有GUEST权限,故接口访问不成功

场景三:登陆wangwu(角色:User,ADMIN),然后访问 /auth/home(配置的USER角色) 和 /auth/admin(配置的ADMIN角色) 路径(,人物角色和路径角色一致,那么两个接口都能访问成功
步骤一:登陆

步骤二:登陆成功

步骤三:访问 /auth/home 和 /auth/admin接口浏览器输入 http://localhost:9901/auth/home 和 http://localhost:9901/auth/admin 都访问成功了


步骤四:访问/auth/hello接口,这个接口是GUEST权限的wangwu是没有的,浏览器输入http://localhost:9901/auth/hello 报错

问题回顾
在上面的配置类里面,虽然配置了有的路径可以不经过验证,但是访问的时候还是会报错403,没有权限,原因时应为接口请方式为post方式,而SpringSecurity为防止CSRF(跨站请求伪造)为拦截出get请求以外的大多数请求方式,
解决方式一:
加上
.csrf().disable()的配置
//访问路径配置
@Override
protected void configure(HttpSecurity http) throws java.lang.Exception {
http
.csrf().disable() //去除csrf攻击的配置,以便除get请求方式,其他请求方式也能访问接口
.authorizeRequests()
.antMatchers("/auth/hello").hasRole("GUEST") //给访问的地址加上角色限制,只有指定的角色才能访问
.antMatchers("/auth/home").hasRole("USER")
.antMatchers("/auth/admin").hasRole("ADMIN")
.antMatchers("/test/health").permitAll() //此路径不需要经过过认证,可以不登录直接请求
.anyRequest().authenticated() //除配置的/test/health路径其他请求都需要认证
.and()
.formLogin() //允许表单登陆
.successForwardUrl("/sys/login"); //自定义表单登陆成功后的跳转路径
}
解决方式二:
前端加上csrf的配置

本文介绍了Spring Security的基本概念,通过一个Spring Cloud工程展示了如何配置和使用Spring Security进行认证和授权。文章详细阐述了不同场景下的测试步骤,包括不同角色访问特定接口的情况,并讨论了在遇到403权限错误时的解决方法,如添加配置或处理CSRF问题。
475

被折叠的 条评论
为什么被折叠?



