首先引入pom依赖
1、resilience 熔断器
2、gateway 网关
3、eureka client 收款定制开发服务注册中心
4、lombok插件
5、actuator状态监控
- <dependencies>
- <!-- 熔断器-->
- <dependency>
- <groupId>io.github.resilience4j</groupId>
- <artifactId>resilience4j-feign</artifactId>
- <version>1.1.0</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
-
- <!-- Gateway -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-gateway</artifactId>
- </dependency>
-
- <!-- 注册中心 -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- <version>2.2.2.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <optional>true</optional>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-actuator</artifactId>
- </dependency>
- </dependencies>
application.yml配置
1、gateway信息
2、actuator状态信息
3、配置eureka server收款定制开发地址及注册信息
4、日志配置
5、获取oauth2的jwt key
- server:
- port: 18890
- spring:
- application:
- name: open-api-gateway
- profiles:
- active: local
- cloud:
- gateway:
- discovery:
- locator:
- enabled: true
- lower-case-service-id: true
- globalcors:
- corsConfigurations:
- '[/**]':
- allowedOrigins: "*"
- allowedMethods: "*"
- default-filters:
- - AddRequestParameter=gateway_type, member
- - AddRequestHeader=gateway_type, member
- management:
- endpoints:
- web:
- exposure:
- include: "*"
- endpoint:
- health:
- show-details: always
-
- eureka:
- instance:
- prefer-ip-address: true
- instance-id: ${spring.cloud.client.ip-address}:${server.port}
- client:
- service-url:
- defaultZone: http://127.0.0.1:22001/eureka
- logging:
- level:
- com.dq.edu: debug
- com:
- netflix:
- discovery: error
- spring:
- security:
- oauth2:
- resourceserver:
- jwt:
- jwk-set-uri: http://127.0.0.1:18889/auth-server/private/jwk_public_key
核心内容:security配置、PermissionFilter收款定制开发鉴权过滤器
1、security配置
- package com.digquant.openapigateway.config;
-
- import com.digquant.openapigateway.entity.Response;
- import lombok.AllArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.core.io.buffer.DataBuffer;
- import org.springframework.core.io.buffer.DataBufferFactory;
- import org.springframework.core.io.buffer.DataBufferUtils;
- import org.springframework.http.HttpMethod;
- import org.springframework.http.MediaType;
- import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
- import org.springframework.security.config.web.server.ServerHttpSecurity;
- import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
- import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter;
- import org.springframework.security.web.server.SecurityWebFilterChain;
- import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
- import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;
- import org.springframework.util.StringUtils;
- import org.springframework.web.server.ServerWebExchange;
- import reactor.core.publisher.Mono;
-
- import java.nio.charset.Charset;
-
- @Slf4j
- @Configuration
- @AllArgsConstructor
- @EnableWebFluxSecurity
- public class SecurityConfig {
-
- private final ReactiveJwtDecoder jwtDecoder;
-
- @Bean
- public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
- http.cors().disable().csrf().disable();
- http
- .authorizeExchange()
- .pathMatchers("/**").permitAll()
- .pathMatchers("/**/public/**").permitAll()
- .pathMatchers("/**/static/**").permitAll()
- .pathMatchers("/*/oauth/**").permitAll()
- .pathMatchers("/actuator/**").permitAll()
- .pathMatchers(HttpMethod.OPTIONS).permitAll()
- .anyExchange().authenticated()
- .and()
- .exceptionHandling()
- .accessDeniedHandler(serverAccessDeniedHandler())
- .authenticationEntryPoint(serverAuthenticationEntryPoint())
- .and()
- .oauth2ResourceServer()
- .jwt()
- .jwtDecoder(jwtDecoder)
- .and()
- .bearerTokenConverter(new ServerBearerTokenAuthenticationConverter());
- return http.build();
- }
-
- @Bean
- public ServerAccessDeniedHandler serverAccessDeniedHandler() {
- return (exchange, denied) -> {
- log.debug("没有权限");
- String errMsg = StringUtils.hasText(denied.getMessage()) ? denied.getMessage() : "没有权限";
- Response result = new Response(1, errMsg);
- return create(exchange, result);
- };
- }
-
- @Bean
- public ServerAuthenticationEntryPoint serverAuthenticationEntryPoint() {
- return (exchange, e) -> {
- log.debug("认证失败");
- String errMsg = StringUtils.hasText(e.getMessage()) ? e.getMessage() : "认证失败";
- Response result = new Response(1, errMsg);
- return create(exchange, result);
- };
- }
-
- private Mono<Void> create(ServerWebExchange exchange, Response result) {
- return Mono.defer(() -> Mono.just(exchange.getResponse()))
- .flatMap(response -> {
- response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
- DataBufferFactory dataBufferFactory = response.bufferFactory();
- DataBuffer buffer = dataBufferFactory.wrap(createErrorMsg(result));
- return response.writeWith(Mono.just(buffer))
- .doOnError(error -> DataBufferUtils.release(buffer));
- });
- }
-
- private byte[] createErrorMsg(Response result) {
- return result.getErrMsg().getBytes(Charset.defaultCharset());
- }
- }
gateway是基于 WebFlux的响应式编程框架,所以在使用securityConfig时采用的注解是@EnableWebFluxSecurity
2、PermissionFilter
- package com.digquant.openapigateway.filter;
-
- import com.digquant.openapigateway.utils.IStrings;
- import lombok.AllArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.core.annotation.Order;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.server.reactive.ServerHttpRequest;
- import org.springframework.security.core.context.ReactiveSecurityContextHolder;
- import org.springframework.security.core.context.SecurityContext;
- import org.springframework.security.oauth2.jwt.Jwt;
- import org.springframework.security.oauth2.server.resource.authentication.AbstractOAuth2TokenAuthenticationToken;
- import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
- import org.springframework.stereotype.Component;
- import org.springframework.web.server.ServerWebExchange;
- import org.springframework.web.server.WebFilter;
- import org.springframework.web.server.WebFilterChain;
- import reactor.core.publisher.Mono;
-
- import java.util.Objects;
-
- @Slf4j
- @Order
- @Component
- @AllArgsConstructor
- public class PermissionFilter implements WebFilter {
-
- @Override
- public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
- return ReactiveSecurityContextHolder.getContext()
- //排除没有Token的
- .filter(Objects::nonNull)
- // //检查该路径是否需要权限
- // .filter(var -> permissionStore.usingPermission(exchange.getRequest().getPath().value()))
- .map(SecurityContext::getAuthentication)
- .map(authentication -> (JwtAuthenticationToken) authentication)
- .doOnNext(jwtAuthenticationToken -> {
- String path = exchange.getRequest().getPath().value();
- log.info("请求 uri {}", path);
- })
- .map(AbstractOAuth2TokenAuthenticationToken::getPrincipal)
- .map(var -> (Jwt) var)
- .map(jwt -> {
- String tokenValue = jwt.getTokenValue();
- ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
- builder.header(HttpHeaders.AUTHORIZATION, IStrings.splice("Bearer ", tokenValue));
- ServerHttpRequest request = builder.build();
- return exchange.mutate().request(request).build();
- })
- .defaultIfEmpty(exchange)
- .flatMap(chain::filter);
- }
- }
1、使用permissionStore来记录uri的权限要求
2、获取到jwtToken时,处理token所携带的权限,用于匹配是否能请求对应资源
1、eureka client
2、spring boot mvc
3、redis 用于存储jwt
4、mysql用于记录用户资源权限
5、oauth2组件
6、httpclient fregn用于用户登陆鉴权
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- <version>2.2.2.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>2.1.1</version>
- </dependency>
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- <version>1.1.21</version>
- </dependency>
-
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.18</version>
- </dependency>
-
- <!-- oauth2-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-oauth2</artifactId>
- <version>2.2.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-security</artifactId>
- <version>2.2.0.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-oauth2-jose</artifactId>
- <version>5.2.2.RELEASE</version>
- </dependency>
- <!-- HttpClient -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- <version>2.2.2.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>io.github.openfeign</groupId>
- <artifactId>feign-okhttp</artifactId>
- <version>10.9</version>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <optional>true</optional>
- </dependency>
-
- </dependencies>
应用配置
- server:
- port: 37766
- spring:
- application:
- name: auth-server
- mvc:
- throw-exception-if-no-handler-found: true
- profiles:
- active: dev
-
- mybatis:
- mapper-locations: classpath:mapper/*.xml
- type-aliases-package: com.digquant.enity.po
-
-
- logging:
- level:
- com:
- digquant:
- dao: info
- file:
- path: /dq/log/new/auth-server
-
-
- digquant:
- authorization:
- auth-jwt-jks: hq-jwt.jks
- auth-jwt-key: hq-jwt
- auth-jwt-password: hq940313
- access-token-validity-seconds: 14400
- refresh-token-validity-seconds: 86400
1、AuthorizationServerConfig配置
- package com.digquant.config;
-
- import com.digquant.dao.CustomRedisTokenStore;
- import com.digquant.enity.JWTProperties;
- import com.digquant.enity.Response;
- import com.digquant.service.OAuthUserService;
- import lombok.AllArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.core.io.ClassPathResource;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.MediaType;
- import org.springframework.http.ResponseEntity;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
- import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
- import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
- import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
- import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
- import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
- import org.springframework.security.oauth2.provider.ClientDetailsService;
- import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
- import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
- import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
- import org.springframework.security.oauth2.provider.token.TokenStore;
- import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
- import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
- import org.springframework.security.web.AuthenticationEntryPoint;
- import org.springframework.security.web.access.AccessDeniedHandler;
-
- import javax.servlet.http.HttpServletResponse;
- import javax.sql.DataSource;
- import java.io.IOException;
-
-
- @Slf4j
- @Configuration
- @AllArgsConstructor
- @EnableAuthorizationServer
- public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
-
- private final JWTProperties jwtProperties;
-
- /**
- * 注入权限验证控制器 支持 password grant type
- */
- private final AuthenticationManager authenticationManager;
-
- /**
- * 数据源
- */
- private final DataSource dataSource;
-
- /**
- * 开启refresh_token
- */
- private final OAuthUserService userService;
-
- /**
- * 采用redis 存储token
- */
- private final RedisConnectionFactory redisConnectionFactory;
-
- @Override
- public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
- security.allowFormAuthenticationForClients()
- .checkTokenAccess("permitAll()")
- .tokenKeyAccess("permitAll()")
- .authenticationEntryPoint(authenticationEntryPoint())
- .accessDeniedHandler(accessDeniedHandler());
- }
-
- @Bean
- public AccessDeniedHandler accessDeniedHandler() {
- return (request, response, accessDeniedException) -> {
- Response result = new Response(1, accessDeniedException.getMessage());
- writerResponse(response, result, HttpStatus.FORBIDDEN.value());
- };
- }
-
- @Bean
- public AuthenticationEntryPoint authenticationEntryPoint() {
- return (request, response, authException) -> {
- Response result = new Response(1, authException.getMessage());
- writerResponse(response, result, HttpStatus.UNAUTHORIZED.value());
- };
- }
-
- private void writerResponse(HttpServletResponse response, Response result, int status) throws IOException {
- response.setStatus(status);
- response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
- response.setCharacterEncoding("UTF-8");
- response.getWriter().print(result.getErrMsg());
- response.getWriter().flush();
- }
-
- @Bean("redisTokenStore")
- public TokenStore redisTokenStore() {
- return new CustomRedisTokenStore(redisConnectionFactory);
- }
-
- @Bean
- public JwtAccessTokenConverter jwtAccessTokenConverter() {
- JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
- jwtAccessTokenConverter.setKeyPair(keyStoreKeyFactory().getKeyPair(jwtProperties.getAuthJwtKey()));
- return jwtAccessTokenConverter;
- }
-
- @Bean
- public KeyStoreKeyFactory keyStoreKeyFactory() {
- return new KeyStoreKeyFactory(new ClassPathResource(jwtProperties.getAuthJwtJks()), jwtProperties.getAuthJwtPassword().toCharArray());
- }
-
- @Bean
- public DefaultTokenServices tokenServices() {
- DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
- defaultTokenServices.setTokenStore(redisTokenStore());
- defaultTokenServices.setTokenEnhancer(jwtAccessTokenConverter());
- defaultTokenServices.setSupportRefreshToken(true);
- defaultTokenServices.setReuseRefreshToken(false);
- defaultTokenServices.setAccessTokenValiditySeconds(jwtProperties.getAccessTokenValiditySeconds());
- defaultTokenServices.setRefreshTokenValiditySeconds(jwtProperties.getRefreshTokenValiditySeconds());
- return defaultTokenServices;
- }
-
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
- //开启密码授权类型
- endpoints
- .authenticationManager(authenticationManager)
- //配置token存储方式
- .tokenStore(redisTokenStore())
- //需要额外配置,用于refres_token
- .userDetailsService(userService)
- //
- .tokenServices(tokenServices())
- .accessTokenConverter(jwtAccessTokenConverter())
- .exceptionTranslator(exceptionTranslator());
- }
-
- @Bean
- public WebResponseExceptionTranslator exceptionTranslator() {
- return exception -> {
- return ResponseEntity.status(HttpStatus.OK).body(new OAuth2Exception(exception.getMessage()));
- };
- }
-
- @Bean
- public ClientDetailsService clientDetails() {
- return new JdbcClientDetailsService(dataSource);
- }
-
- @Override
- public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
- // clients.withClientDetails(clientDetails());
- clients.inMemory()
- .withClient("open_api")
- .authorizedGrantTypes("password","refresh_token")
- .authorities("USER")
- .scopes("read", "write")
- .resourceIds("auth-server")
- .secret(new BCryptPasswordEncoder().encode("digquant"));
-
- }
- }
2、ResourceServerConfig 资源服务配置
- package com.digquant.config;
-
- import lombok.AllArgsConstructor;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.core.annotation.Order;
- import org.springframework.http.HttpMethod;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
- import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
- import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
- import org.springframework.security.web.AuthenticationEntryPoint;
- import org.springframework.security.web.access.AccessDeniedHandler;
-
- @Order(6)
- @Configuration
- @AllArgsConstructor
- @EnableResourceServer
- public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
- private final AccessDeniedHandler accessDeniedHandler;
-
- private final AuthenticationEntryPoint authenticationEntryPoint;
-
- @Override
- public void configure(HttpSecurity http) throws Exception {
- http.csrf().disable();
- http
- .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
- .and().authorizeRequests()
- .antMatchers("/swagger-ui.html","/webjars/**").permitAll()
- .antMatchers("/oauth/**").permitAll()
- .antMatchers("/actuator/**").permitAll()
- .antMatchers("/").permitAll()
- .antMatchers(HttpMethod.OPTIONS).permitAll()
- .anyRequest().permitAll();
- }
-
- @Override
- public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
- resources.authenticationEntryPoint(authenticationEntryPoint)
- .accessDeniedHandler(accessDeniedHandler)
- .resourceId("auth-server");
- }
- }
3、SecurityConfig配置
- package com.digquant.config;
-
- import com.digquant.service.CustomAuthenticationProvider;
- import com.digquant.service.OAuthUserService;
- import lombok.AllArgsConstructor;
- import org.springframework.boot.autoconfigure.AutoConfigureAfter;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.core.annotation.Order;
- import org.springframework.http.HttpMethod;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.authentication.AuthenticationProvider;
- import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.config.annotation.web.builders.WebSecurity;
- import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.config.http.SessionCreationPolicy;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- import org.springframework.security.crypto.password.PasswordEncoder;
-
- @Order(7)
- @Configuration
- @EnableWebSecurity
- @AllArgsConstructor
- @AutoConfigureAfter(ResourceServerConfig.class)
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
-
- private final OAuthUserService userService;
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http.cors().and().csrf().disable();
- http.authorizeRequests()
- .antMatchers("/oauth/**").permitAll()
- .antMatchers("/public/**").permitAll()
- .antMatchers("/actuator/**").permitAll()
- .antMatchers("/private/**").permitAll()
- .antMatchers("/").permitAll()
- .antMatchers(HttpMethod.OPTIONS).permitAll()
- .anyRequest().permitAll()
- .and()
- .sessionManagement()
- .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
- }
-
- @Override
- public void configure(WebSecurity web) throws Exception {
- web.ignoring().antMatchers("/favor.ico");
- }
-
- @Bean
- @Override
- public AuthenticationManager authenticationManagerBean() throws Exception {
- return super.authenticationManagerBean();
- }
-
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.authenticationProvider(authenticationProvider());
- }
-
- @Bean
- public PasswordEncoder passwordEncoder() {
- return new BCryptPasswordEncoder();
- }
-
- @Bean
- public AuthenticationProvider authenticationProvider() {
- CustomAuthenticationProvider provider = new CustomAuthenticationProvider()
- .setUserDetailsService(userService)
- .setPasswordEncoder(passwordEncoder());
- provider.setHideUserNotFoundExceptions(false);
- return provider;
- }
-
- }
4、JwkController 用于gateway 请求jwt私钥
- package com.digquant.controller;
-
- import com.digquant.enity.JWTProperties;
- import com.nimbusds.jose.jwk.JWKSet;
- import com.nimbusds.jose.jwk.RSAKey;
- import io.swagger.annotations.Api;
- import io.swagger.annotations.ApiOperation;
- import lombok.AllArgsConstructor;
- import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
- import org.springframework.web.bind.annotation.*;
-
- import java.security.interfaces.RSAPublicKey;
- import java.util.Map;
-
- @Api(tags = "jwk")
- @RestController
- @RequestMapping("/private")
- @AllArgsConstructor
- public class JwkController {
- private final KeyStoreKeyFactory keyStoreKeyFactory;
-
- private final JWTProperties jwtProperties;
-
- @ApiOperation("获取jwk")
- @PostMapping("/jwk_public_key")
- public Map<String, Object> getKey() {
- RSAPublicKey publicKey = (RSAPublicKey) keyStoreKeyFactory.getKeyPair(jwtProperties.getAuthJwtKey()).getPublic();
- RSAKey key = new RSAKey.Builder(publicKey).build();
- return new JWKSet(key).toJSONObject();
- }
-
- }
5、用户鉴权服务,获取用户信息
- package com.digquant.service;
-
- import com.digquant.enity.to.AuthenticationTO;
- import com.digquant.enums.LoginType;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.core.userdetails.UsernameNotFoundException;
- import org.springframework.stereotype.Component;
- import org.springframework.util.CollectionUtils;
-
- import java.util.List;
- import java.util.Map;
-
- @Slf4j
- @Component
- public class OAuthUserService implements UserDetailsService {
-
- @Autowired(required = false)
- private List<OAuthUserProcessor> oAuthUserProcessors;
-
- public UserDetails loadUser(String username, UsernamePasswordAuthenticationToken authentication) {
- AuthenticationTO authenticationTO = new AuthenticationTO();
- authenticationTO.setUsername(username);
- authenticationTO.setPassword((String) authentication.getCredentials());
-
- Map map = (Map) authentication.getDetails();
- String scope = (String) map.get("scope");
- String grantType = (String) map.get("grant_type");
- String clientId = (String) map.get("client_id");
-
- authenticationTO.setScope(scope);
- authenticationTO.setGrantType(grantType);
- authenticationTO.setLoginType(LoginType.PASSWORD);
- authenticationTO.setClientId(clientId);
-
- if (log.isDebugEnabled()) {
- log.debug("请求认证参数:{}", authenticationTO);
- }
- if (!CollectionUtils.isEmpty(oAuthUserProcessors)) {
- //目前只支持客户端密码登录方式
- for (OAuthUserProcessor oAuthUserProcessor : oAuthUserProcessors) {
- if (oAuthUserProcessor.support(authenticationTO)) {
- UserDetails userDetails = oAuthUserProcessor.findUser(authenticationTO);
- //TODO 需要加载OpenApi用户的权限
- loadAuthorities(userDetails, authenticationTO);
- return userDetails;
- }
- }
- }
- throw new UsernameNotFoundException("用户不存在");
- }
-
- private void loadAuthorities(UserDetails userDetails, AuthenticationTO authenticationTO) {
-
- }
-
- @Override
- public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
- return null;
- }
- }