本项目的登录认证和鉴权功能在不同的服务器模块里面运行,其中登录认证功能在内部的应用服务器里面实现,鉴权功能在网关实现,这里着重讲springsecurity在gateway网关里面的鉴权功能的配置。

1、核心配置类如下

@EnableWebFluxSecurity
public class SecurityWebfluxConfig {

    @Bean
    SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http.authorizeExchange()
                .pathMatchers("/sys/faceLogin/**","/sys/login").permitAll()
                .pathMatchers(HttpMethod.GET,"/company/department/{id}").hasAuthority("department:findById")
                .anyExchange().authenticated()
                .and().csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint(new UnauthorizedEntryPoint())
                .accessDeniedHandler(new AccessDeniedHandler())
                .and().cors().configurationSource(corsConfigurationSource());

        return http.build();
    }

    private CorsConfigurationSource corsConfigurationSource() {
        CorsConfigurationSource source=new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");    //同源配置,*表示任何请求都视为同源,若需指定ip和端口可以改为如“localhost:8080”,多个以“,”分隔;
        corsConfiguration.addAllowedHeader("*");//header,允许哪些header,本案中使用的是token,此处可将*替换为token;
        corsConfiguration.addAllowedMethod("*");    //允许的请求方法,PSOT、GET等
        ((UrlBasedCorsConfigurationSource) source).registerCorsConfiguration("/**",corsConfiguration); //配置允许跨域访问的url
        return source;
    }

    @Bean
    public WebSessionIdResolver sessionIdResolver(){
        HeaderWebSessionIdResolver sessionIdResolver=new HeaderWebSessionIdResolver();
        sessionIdResolver.setHeaderName("Authorization");
        return sessionIdResolver;
    }
}

其中,配置了部分访问路径所需的权限,未登录的处理方法以及没有权限的处理方法,支持跨域以及从请求头获取sessionid创建session解析器。

2、创建未登录的处理方法,代码如下

public class UnauthorizedEntryPoint implements ServerAuthenticationEntryPoint {
    @Override
    public Mono<Void> commence(ServerWebExchange serverWebExchange, AuthenticationException e) {
        ServerHttpResponse response = serverWebExchange.getResponse();
        return ResponseUtil.out(response,new Result(ResultCode.UNAUTHENTICATED));
    }
}

3、创建没有权限的处理方法,代码如下

public class AccessDeniedHandler implements ServerAccessDeniedHandler {
    @Override
    public Mono<Void> handle(ServerWebExchange serverWebExchange, AccessDeniedException e) {
        ServerHttpResponse response = serverWebExchange.getResponse();
        return ResponseUtil.out(response,new Result(ResultCode.UNAUTHORISE));
    }
}

4、这里面用到了一些工具类,其中ResponseUtil用于发送响应数据,代码如下

public class ResponseUtil {

    @SneakyThrows
    public static Mono<Void> out(ServerHttpResponse response, Result result) {
        ObjectMapper objectMapper=new ObjectMapper();
        byte[] bits = objectMapper.writeValueAsString(result).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        //指定编码,否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
}

Result和ResultCode用于封装json响应数据。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐