Angular 6集成Spring Boot 2,Spring Security,JWT和CORS系列:六、Spring Security的授权

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的授权,目前基本这样,感觉还挺接单的。

展开阅读全文

没有更多推荐了,返回首页