赞
踩
鉴权:即访问控制,控制谁能访问那些资源;进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无发访问的,如图所示:
基于资源的权限控制
RBAC基于资源的访问控制是以资源为中心进行访问控制,企业中常用的权限管理方法,实现思路是:将系统操作的每个URL配置在资源表中,将资源对应到角色,将角色分配给用户,用户访问系统功能的Filter进行过滤,过滤器获取到用户访问的URL,只要访问的URL是用户分配的角色中的URL是用户分配角色中的URL则放行继续访问,其具体流程如下:
鉴权流程
ReactiveAuthorizationManager:主要是权限鉴定的过程,主要包含:拦截获得URL、jwt令牌校验、校验权限
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.ReactiveAuthorizationManager; import org.springframework.security.core.Authentication; import org.springframework.security.web.server.authorization.AuthorizationContext; import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.util.List; import java.util.Set; /** * @ClassName AuthorizeConfigManager.java * @Description 鉴权用户权限 */ @Slf4j @Component @EnableConfigurationProperties(SecurityProperties.class) public class JwtReactiveAuthorizeManager implements ReactiveAuthorizationManager<AuthorizationContext> { private AntPathMatcher antPathMatcher = new AntPathMatcher(); @Autowired SecurityProperties securityProperties; @Autowired JwtTokenManager jwtTokenManager; @Override public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext authorizationContext) { //拦截获得url路径 ServerWebExchange exchange = authorizationContext.getExchange(); ServerHttpRequest request = exchange.getRequest(); String path = request.getURI().getPath(); log.info("===============进入鉴权url:{}==========",path); //jwt令牌校验 String jwtToken = request.getHeaders().getFirst(SuperConstant.JWT_TOKEN_HEADER); boolean flag = jwtTokenManager.isVerifyToken(jwtToken); if (!flag){ return Mono.justOrEmpty(new AuthorizationDecision(false)); } //校验权限 UserVo userVo = JSONObject .parseObject(jwtTokenManager.getCurrentUser(jwtToken).toString(),UserVo.class); Set<String> resources = userVo.getResources(); AuthorizationDecision authorizationDecision = null; //支持restfull String methodValue = request.getMethodValue(); for (String resource : resources) { if (antPathMatcher.match(resource, methodValue+path)) { log.info("用户请求API校验通过,GrantedAuthority:{},Path:{} ",resource, path); authorizationDecision = new AuthorizationDecision(true); return Mono.justOrEmpty(authorizationDecision); } } authorizationDecision = new AuthorizationDecision(false); log.info("用户请求API校验未通过,Path:{} ",path); return Mono.justOrEmpty(authorizationDecision); } }
用户无权限处理
import io.netty.util.CharsetUtil; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.server.ServerAuthenticationEntryPoint; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * @ClassName JsonAuthenticationEntryPoint.java * @Description 用来解决用户访问无权限资源时的异常 */ @Component public class JsonServerAuthenticationEntryPoint implements ServerAuthenticationEntryPoint { @Override public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException e) { //请求状态指定 ServerHttpResponse response = exchange.getResponse(); response.setStatusCode(HttpStatus.UNAUTHORIZED); response.getHeaders().set(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8"); //返回结果封装 ResponseWrap<Boolean> responseWrap = ResponseWrapBuild.build(AuthEnum.NEED_LOGIN, false); String result = JSONObject.toJSONString(responseWrap); DataBuffer buffer = response.bufferFactory().wrap(result.getBytes(CharsetUtil.UTF_8)); return response.writeWith(Mono.just(buffer)); } }
退出处理
import io.netty.util.CharsetUtil; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.security.core.Authentication; import org.springframework.security.web.server.WebFilterExchange; import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; /** * @ClassName JsonServerLogoutSuccessHandler.java * @Description 退出成功 */ @Component public class JsonServerLogoutSuccessHandler implements ServerLogoutSuccessHandler { @Override public Mono<Void> onLogoutSuccess(WebFilterExchange exchange, Authentication authentication) { //指定请求状态 ServerHttpResponse response = exchange.getExchange().getResponse(); response.setStatusCode(HttpStatus.OK); response.getHeaders().set(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8"); //返回封装结果 ResponseWrap<Boolean> responseWrap = ResponseWrapBuild.build(AuthEnum.SUCCEED, true); String result = JSONObject.toJSONString(responseWrap); DataBuffer buffer = response.bufferFactory().wrap(result.getBytes(CharsetUtil.UTF_8)); return response.writeWith(Mono.just(buffer)); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。