Spring Security的授权,相对于认证来说,使用上比较简单。
一、工程中使用Spring Security的步骤:
第一步、工程依赖中引入依赖包。
第二步、继承WebSecurityConfigurerAdapter,使用@Configuration、@EnableWebSecurity声明这是一个配置文件,启用Spring Security的WebSecurity功能。
第三步、注册认证相关类(密码的编码解码器、UserDetailsService实现)。
第四步、重载config,配置AuthenticationManagerBuilder,使用注册的认证相关类。
第五步、重载config,配置HttpSecurity,开始认证和授权的配置。
二、身份认证(Authentication)
身份证,存在各种特殊的需求。Spring Security允许我们做各种扩展,只要在过滤器链上加入认证方法,然后在HttpSecurity配置中加入即可。
三、授权(authorization)
Spring Security的授权,在使用上可以有下列情况:
1、不做任何限制
http.authorizeRequests().anyRequest().permitAll();
2、指定路径放行,其余需要认证才放行
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated();
3、指定路径的某种访问方法放行,其余需要认证才放行
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers(HttpMethod.GET, "/home/**").permitAll()
.anyRequest().authenticated();
4、指定路径禁止访问
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/swagger-ui.html").denyAll()
.anyRequest().authenticated();
这样配置,生产环境中禁用swagger即可实现。
5、根据角色访问才能某个路径
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/swagger-ui.html").denyAll()
.antMatchers("/manager/**").hasRole("ADMIN")
.antMatchers("/teacher/**").hasRole("TEACHER")
.antMatchers("/member/vip/**").hasAnyRole("ADMIN","TEACHER","VIP")
.anyRequest().authenticated();
这个配置:
A、所有访客都可访问login
B、所有访客都不能访问swagger
C、登录(身份认证)之后的访客,根据角色,拥有不同的访问权限
.拥有ADMIN角色的用户,可以访问manager、member/vip,不能访问teacher;
.拥有TEACHER角色的用户,可以访问teacher、member/vip,不能访问manager;
.拥有VIP角色的用户,可以访问member/vip,不能访问manager、teacher;
.其它用户,不能访问manager、teacher、member/vip
系统中要使用这种配置,在UserDetails中必须有正确Authorities。
6、系统根据RBAC模式,使用数据库保存的用户角色权限
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/swagger-ui.html").denyAll()
.anyRequest().access("@hasPermissionService.hasPermission(request,authentication)");
这么简单?
没错,配置就这么简单。
站在巨人的肩膀上,就是爽啊。
在access中配置的@hasPermissionService.hasPermission(request,authentication)可以如下理解:
A、@表示引用等等的
B、hasPermissionService,表示系统在Spring中注册的一个bean,它的名字是hasPermissionService
C、hasPermission,hasPermissionService的一个方法,它的定义如下
public interface HasPermissionService {
boolean hasPermission(HttpServletRequest request,Authentication authentication);
}
它的实现,也可以如下
@Component("hasPermissionService")
public class HasPermissionServiceImpl implements HasPermissionService {
private AntPathMatcher antPathMatcher = new AntPathMatcher();
@Autowired
private SysPermissionService sysPermissionService;
@Override
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
Long startTime=System.currentTimeMillis();
Object principal = authentication.getPrincipal();
boolean result=false;
if (principal instanceof UserDetails) {
UserDetails userDetails=(UserDetails)principal;
Object[] authorities=userDetails.getAuthorities().toArray();
String userId=authorities[0].toString();
List<SysPermission> sysPermissiones=sysPermissionService.findByUserId(userId);
for (SysPermission sysPermission : sysPermissiones) {
//System.out.println("[url="+sysPermission.getLink()+"] [method="+sysPermission.getMethod()+"] URI=["+request.getRequestURI()+"] [URL="+request.getRequestURL()+"]");
if (antPathMatcher.match(sysPermission.getLink(), request.getRequestURI())) {
//当权限表权限的method为ALL时表示拥有此路径的所有请求方式权利。
if (sysPermission.getMethod().equals(request.getMethod()) || "ALL".equals(sysPermission.getMethod())) {
result = true;
break;
}
}
}
}
System.out.println("hasPermission处理时间:"+ (System.currentTimeMillis()-startTime));
return result;
}
}
这个实现自定义,想怎样玩就怎样玩。
好的,我使用Spring Security的授权,目前基本这样,感觉还挺接单的。