mirror of
https://gitee.com/youlaitech/youlai-mall.git
synced 2024-12-23 05:00:25 +08:00
docs:授权服务配置注释完善
This commit is contained in:
parent
e1d52acda7
commit
a1e53c3aba
@ -58,7 +58,6 @@
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- nacos 依赖-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
@ -68,22 +67,15 @@
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-oauth2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.nimbusds</groupId>
|
||||
<artifactId>nimbus-jose-jwt</artifactId>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-jose</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -16,13 +16,17 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests()
|
||||
.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
|
||||
.and().authorizeRequests().antMatchers("/rsa/publicKey").permitAll()
|
||||
.antMatchers("/v2/api-docs").permitAll()
|
||||
.anyRequest().permitAll();
|
||||
http
|
||||
.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
|
||||
.and()
|
||||
.authorizeRequests().antMatchers("/rsa/publicKey").permitAll().anyRequest().authenticated()
|
||||
.and()
|
||||
.csrf().disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果不配置SpringBoot会自动配置一个AuthenticationManager,覆盖掉内存中的用户
|
||||
*/
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return super.authenticationManagerBean();
|
||||
|
@ -55,8 +55,6 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 认证依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
@ -69,10 +67,7 @@
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-jose</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.nimbusds</groupId>
|
||||
<artifactId>nimbus-jose-jwt</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -1,12 +1,11 @@
|
||||
package com.youlai.gateway.auth;
|
||||
|
||||
package com.youlai.gateway.component;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.nimbusds.jose.JWSObject;
|
||||
import com.youlai.admin.api.dto.UserDTO;
|
||||
import com.youlai.common.core.constant.AuthConstants;
|
||||
import com.youlai.gateway.config.WhiteUrlsConfig;
|
||||
import com.youlai.gateway.config.WhiteListConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpMethod;
|
||||
@ -29,7 +28,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 鉴权管理器,用于判断是否有资源的访问权限
|
||||
* 鉴权管理器
|
||||
*/
|
||||
@Component
|
||||
public class AuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {
|
||||
@ -38,21 +37,21 @@ public class AuthorizationManager implements ReactiveAuthorizationManager<Author
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Autowired
|
||||
private WhiteUrlsConfig whiteUrlsConfig;
|
||||
private WhiteListConfig whiteListConfig;
|
||||
|
||||
@Override
|
||||
public Mono<AuthorizationDecision> check(Mono<Authentication> mono, AuthorizationContext authorizationContext) {
|
||||
ServerHttpRequest request = authorizationContext.getExchange().getRequest();
|
||||
URI uri = request.getURI();
|
||||
//白名单路径直接放行
|
||||
// 白名单路径直接放行
|
||||
PathMatcher pathMatcher = new AntPathMatcher();
|
||||
List<String> whiteUrls = whiteUrlsConfig.getUrls();
|
||||
List<String> whiteUrls = whiteListConfig.getUrls();
|
||||
for (String ignoreUrl : whiteUrls) {
|
||||
if (pathMatcher.match(ignoreUrl, uri.getPath())) {
|
||||
return Mono.just(new AuthorizationDecision(true));
|
||||
}
|
||||
}
|
||||
//对应跨域的预检请求直接放行
|
||||
// 对应跨域的预检请求直接放行
|
||||
if (request.getMethod() == HttpMethod.OPTIONS) {
|
||||
return Mono.just(new AuthorizationDecision(true));
|
||||
}
|
||||
@ -97,7 +96,7 @@ public class AuthorizationManager implements ReactiveAuthorizationManager<Author
|
||||
.filter(Authentication::isAuthenticated)
|
||||
.flatMapIterable(Authentication::getAuthorities)
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.any(roleId -> authorities.contains(roleId)) // 判断用户角色中是否有访问资源权限的角色,一个就好
|
||||
.any(roleId -> authorities.contains(roleId))
|
||||
.map(AuthorizationDecision::new)
|
||||
.defaultIfEmpty(new AuthorizationDecision(false));
|
||||
|
@ -17,10 +17,10 @@ import reactor.core.publisher.Mono;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* 无权限访问自定义异常
|
||||
* 无权访问自定义响应
|
||||
*/
|
||||
@Component
|
||||
public class AccessDeniedHandler implements ServerAccessDeniedHandler {
|
||||
public class CustomServerAccessDeniedHandler implements ServerAccessDeniedHandler {
|
||||
|
||||
@Override
|
||||
public Mono<Void> handle(ServerWebExchange exchange, AccessDeniedException e) {
|
@ -20,7 +20,7 @@ import java.nio.charset.Charset;
|
||||
* 无效token自定义异常
|
||||
*/
|
||||
@Component
|
||||
public class AuthExceptionEntryPoint implements ServerAuthenticationEntryPoint {
|
||||
public class CustomServerAuthenticationEntryPoint implements ServerAuthenticationEntryPoint {
|
||||
@Override
|
||||
public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException e) {
|
||||
ServerHttpResponse response=exchange.getResponse();
|
@ -22,7 +22,7 @@ public class CorsConfig {
|
||||
config.setAllowCredentials(true);
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
|
||||
return new CorsWebFilter(source);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ package com.youlai.gateway.config;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.youlai.common.core.constant.AuthConstants;
|
||||
import com.youlai.gateway.auth.AuthorizationManager;
|
||||
import com.youlai.gateway.component.AuthExceptionEntryPoint;
|
||||
import com.youlai.gateway.component.AccessDeniedHandler;
|
||||
import com.youlai.gateway.filter.WhiteUrlsRemoveJwtFilter;
|
||||
import com.youlai.gateway.component.AuthorizationManager;
|
||||
import com.youlai.gateway.component.CustomServerAuthenticationEntryPoint;
|
||||
import com.youlai.gateway.component.CustomServerAccessDeniedHandler;
|
||||
import com.youlai.gateway.filter.WhiteListRemoveJwtFilter;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -31,37 +31,36 @@ import reactor.core.publisher.Mono;
|
||||
public class ResourceServerConfig {
|
||||
|
||||
private AuthorizationManager authorizationManager;
|
||||
private AccessDeniedHandler accessDeniedHandler;
|
||||
private AuthExceptionEntryPoint authExceptionEntryPoint;
|
||||
private WhiteUrlsConfig whiteUrlsConfig;
|
||||
private WhiteUrlsRemoveJwtFilter whiteUrlsRemoveJwtFilter;
|
||||
private CustomServerAccessDeniedHandler customServerAccessDeniedHandler;
|
||||
private CustomServerAuthenticationEntryPoint customServerAuthenticationEntryPoint;
|
||||
private WhiteListConfig whiteListConfig;
|
||||
private WhiteListRemoveJwtFilter whiteListRemoveJwtFilter;
|
||||
|
||||
@Bean
|
||||
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
|
||||
http.oauth2ResourceServer().jwt()
|
||||
.jwtAuthenticationConverter(jwtAuthenticationConverter());
|
||||
// 自定义处理JWT请求头过期或签名错误的结果
|
||||
http.oauth2ResourceServer().authenticationEntryPoint(authExceptionEntryPoint);
|
||||
http.oauth2ResourceServer().authenticationEntryPoint(customServerAuthenticationEntryPoint);
|
||||
// 对白名单路径,直接移除JWT请求头
|
||||
http.addFilterBefore(whiteUrlsRemoveJwtFilter, SecurityWebFiltersOrder.AUTHENTICATION);
|
||||
http.addFilterBefore(whiteListRemoveJwtFilter, SecurityWebFiltersOrder.AUTHENTICATION);
|
||||
http.authorizeExchange()
|
||||
.pathMatchers(ArrayUtil.toArray(whiteUrlsConfig.getUrls(),String.class)).permitAll()
|
||||
.pathMatchers(ArrayUtil.toArray(whiteListConfig.getUrls(),String.class)).permitAll()
|
||||
.anyExchange().access(authorizationManager)
|
||||
.and()
|
||||
.exceptionHandling()
|
||||
.accessDeniedHandler(accessDeniedHandler) // 处理未授权
|
||||
.authenticationEntryPoint(authExceptionEntryPoint) //处理未认证
|
||||
.accessDeniedHandler(customServerAccessDeniedHandler) // 处理未授权
|
||||
.authenticationEntryPoint(customServerAuthenticationEntryPoint) //处理未认证
|
||||
.and().csrf().disable();
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* https://blog.csdn.net/qq_24230139/article/details/105091273
|
||||
* @linkhttps://blog.csdn.net/qq_24230139/article/details/105091273
|
||||
* ServerHttpSecurity没有将jwt中authorities的负载部分当做Authentication
|
||||
* 需要把jwt的Claim中的authorities加入
|
||||
* 方案:重新定义ReactiveAuthenticationManager权限管理器,默认转换器JwtGrantedAuthoritiesConverter
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
|
@ -1,15 +1,18 @@
|
||||
package com.youlai.gateway.config;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 白名单配置
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "white")
|
||||
public class WhiteUrlsConfig {
|
||||
@ConfigurationProperties(prefix = "white-list")
|
||||
public class WhiteListConfig {
|
||||
|
||||
private List<String> urls;
|
||||
|
||||
}
|
@ -14,15 +14,15 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 将登录用户的JWT转换成用户信息过滤器
|
||||
* JWT转换成用户信息过滤器
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AuthGlobalFilter implements GlobalFilter, Ordered {
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
|
||||
String token = exchange.getRequest().getHeaders().getFirst(AuthConstants.JWT_TOKEN_HEADER);
|
||||
if (StrUtil.isBlank(token)) {
|
||||
return chain.filter(exchange);
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.youlai.gateway.filter;
|
||||
|
||||
import com.youlai.common.core.constant.AuthConstants;
|
||||
import com.youlai.gateway.config.WhiteUrlsConfig;
|
||||
import com.youlai.gateway.config.WhiteListConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -19,10 +19,10 @@ import java.util.List;
|
||||
* 白名单路径移除JWT请求头
|
||||
*/
|
||||
@Component
|
||||
public class WhiteUrlsRemoveJwtFilter implements WebFilter {
|
||||
public class WhiteListRemoveJwtFilter implements WebFilter {
|
||||
|
||||
@Autowired
|
||||
private WhiteUrlsConfig whiteUrlsConfig;
|
||||
private WhiteListConfig whiteListConfig;
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
@ -31,7 +31,7 @@ public class WhiteUrlsRemoveJwtFilter implements WebFilter {
|
||||
PathMatcher pathMatcher=new AntPathMatcher();
|
||||
|
||||
//白名单路径移除JWT请求头
|
||||
List<String> ignoreUrls = whiteUrlsConfig.getUrls();
|
||||
List<String> ignoreUrls = whiteListConfig.getUrls();
|
||||
for (String ignoreUrl : ignoreUrls) {
|
||||
if (pathMatcher.match(ignoreUrl, uri.getPath())) {
|
||||
request = exchange.getRequest().mutate().header(AuthConstants.JWT_TOKEN_HEADER, "").build();
|
@ -1,59 +0,0 @@
|
||||
package com.youlai.gateway.handler;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.youlai.common.core.result.Result;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.io.buffer.DataBufferFactory;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.handler.ResponseStatusExceptionHandler;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 网关异常通用处理器,只作用在webflux 环境下 , 优先级低于 {@link ResponseStatusExceptionHandler} 执行
|
||||
*
|
||||
* @author 冷酱
|
||||
* @date 2020/5/26
|
||||
*/
|
||||
@Slf4j
|
||||
@Order(-1)
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class GlobalExceptionHandler implements ErrorWebExceptionHandler {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@Override
|
||||
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
|
||||
if (response.isCommitted()) {
|
||||
return Mono.error(ex);
|
||||
}
|
||||
|
||||
// header set
|
||||
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
|
||||
if (ex instanceof ResponseStatusException) {
|
||||
response.setStatusCode(((ResponseStatusException) ex).getStatus());
|
||||
}
|
||||
|
||||
return response.writeWith(Mono.fromSupplier(() -> {
|
||||
DataBufferFactory bufferFactory = response.bufferFactory();
|
||||
try {
|
||||
return bufferFactory.wrap(objectMapper.writeValueAsBytes(Result.error(ex.getMessage())));
|
||||
}
|
||||
catch (JsonProcessingException e) {
|
||||
log.error("Error writing response", ex);
|
||||
return bufferFactory.wrap(new byte[0]);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user