智能摘要文章源自JAVA秀-https://www.javaxiu.com/66807.html
动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。基于微服务的思想,构建在B2C电商场景下的项目实战。欢迎加入我的知识星球,一起探讨架构,交流源码。MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。提供近3W行代码的SpringBoot示例,以及超6W行代码的电商微服务项目。文章源自JAVA秀-https://www.javaxiu.com/66807.html
原文约 7026 字 | 图片 19 张 | 建议阅读 15 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/66807.html
SpringCloud+Gateway+Security 搭建微服务统一认证授权(附源码)
点击关注 ? Java基基 文章源自JAVA秀-https://www.javaxiu.com/66807.html
点击上方“Java基基”,选择“设为星标”文章源自JAVA秀-https://www.javaxiu.com/66807.html
做积极的人,而不是积极废人!文章源自JAVA秀-https://www.javaxiu.com/66807.html
每天 14:00 更新文章,每天掉亿点点头发...文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
源码精品专栏文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
原创 | Java 2021 超神之路,很肝~文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
中文详细注释的开源项目文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
RPC 框架 Dubbo 源码解析文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
网络应用框架 Netty 源码解析文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
消息中间件 RocketMQ 源码解析文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
数据库中间件 Sharding-JDBC 和 MyCAT 源码解析文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
作业调度中间件 Elastic-Job 源码解析文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
分布式事务中间件 TCC-Transaction 源码解析文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
Eureka 和 Hystrix 源码解析文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
Java 并发源码文章源自JAVA秀-https://www.javaxiu.com/66807.html
来源:blog.csdn.net/qq_34125999/文章源自JAVA秀-https://www.javaxiu.com/66807.html
article/details/107579972/文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
1 概述文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
2 父工程文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
3 uaa认证服务搭建文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
4 Gateway服务搭建文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
5 School微服务文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
6 集成测试文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
7 Github地址文章源自JAVA秀-https://www.javaxiu.com/66807.html
1 概述
SpringCloud Gateway Security oauth2.0 搭建微服务统一认证授权。文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
项目概述:文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
common
:公用代码,实体、工具类等等…文章源自JAVA秀-https://www.javaxiu.com/66807.html -
gateway
:网关文章源自JAVA秀-https://www.javaxiu.com/66807.html -
uaa
:用户登录认证服务文章源自JAVA秀-https://www.javaxiu.com/66807.html -
school
:微服务文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
环境概述:文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
SpringBoot 版本:2.3.1.RELEASE文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
SpringCloud版本:Hoxton.SR6文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
SpringCloudAlibaba:2.2.1.RELEASE文章源自JAVA秀-https://www.javaxiu.com/66807.html
-
MybatisPlus:3.3.2文章源自JAVA秀-https://www.javaxiu.com/66807.html
技能要求:文章源自JAVA秀-https://www.javaxiu.com/66807.html
需要掌握SpringCloud 、SpringCloudAlibaba 基础使用,了解RBAC、OAuth2.0、JWT。文章源自JAVA秀-https://www.javaxiu.com/66807.html
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。文章源自JAVA秀-https://www.javaxiu.com/66807.html
项目地址:https://github.com/YunaiV/ruoyi-vue-pro文章源自JAVA秀-https://www.javaxiu.com/66807.html
2 父工程
父工程pom依赖:文章源自JAVA秀-https://www.javaxiu.com/66807.html
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.rosh</groupId> <artifactId>demo</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>gateway</module> <module>uaa</module> <module>school</module> <module>common</module> </modules> <packaging>pom</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <!--spring boot--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.3.1.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <!--spring cloud--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR6</version> <type>pom</type> <scope>import</scope> </dependency> <!--spring cloud alibaba 2.1.0.RELEASE--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.1.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.71</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build></project>
基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。文章源自JAVA秀-https://www.javaxiu.com/66807.html
项目地址:https://github.com/YunaiV/onemall文章源自JAVA秀-https://www.javaxiu.com/66807.html
3 uaa认证服务搭建
文章源自JAVA秀-https://www.javaxiu.com/66807.html
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>demo</artifactId> <groupId>com.rosh</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>uaa</artifactId> <dependencies> <!--springboot && spring cloud--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--授权--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <!--数据库--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.2</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>com.rosh</groupId> <artifactId>common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies></project>
server: port: 8500spring: application: name: uaa-server cloud: nacos: discovery: server-addr: 192.168.226.39:8848 datasource: url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.jdbc.Drivermybatis-plus: mapper-locations: classpath:/mapper/*.xml global-config: db-config: id-type: auto#暴露监控management: endpoints: web: exposure: include: '*'
文章源自JAVA秀-https://www.javaxiu.com/66807.html
(1) TokenConfig文章源自JAVA秀-https://www.javaxiu.com/66807.html
@Configurationpublic class TokenConfig { /** * 秘钥串 */ private static final String SIGNING_KEY = "uaa"; @Bean public TokenStore tokenStore() { return new JwtTokenStore(accessTokenConverter()); } @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(SIGNING_KEY); return converter; } /** * 配置令牌管理 */ @Bean public AuthorizationServerTokenServices tokenService(ClientDetailsService clientDetailsService,TokenStore tokenStore ,JwtAccessTokenConverter accessTokenConverter) { DefaultTokenServices service = new DefaultTokenServices(); service.setClientDetailsService(clientDetailsService); service.setSupportRefreshToken(true); service.setTokenStore(tokenStore); TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); tokenEnhancerChain.setTokenEnhancers(Collections.singletonList(accessTokenConverter)); service.setTokenEnhancer(tokenEnhancerChain); return service; } /** * 授权码存储方式 */ @Bean public AuthorizationCodeServices authorizationCodeServices(DataSource dataSource) { return new JdbcAuthorizationCodeServices(dataSource); }}
(2) AuthorizationServer文章源自JAVA秀-https://www.javaxiu.com/66807.html
@Configuration@EnableAuthorizationServerpublic class AuthorizationServer extends AuthorizationServerConfigurerAdapter { @Autowired private AuthorizationCodeServices authorizationCodeServices; @Autowired private AuthenticationManager authenticationManager; @Autowired private AuthorizationServerTokenServices tokenService; @Autowired @Qualifier("myClientDetailsService") private ClientDetailsService clientService; /** * 配置客户端详细信息服务 */ @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.withClientDetails(clientService); } @Bean("myClientDetailsService") public ClientDetailsService clientDetailsService(DataSource dataSource, PasswordEncoder passwordEncoder) { JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource); clientDetailsService.setPasswordEncoder(passwordEncoder); return clientDetailsService; } /** * 令牌访问端点 */ @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) { endpoints .authenticationManager(authenticationManager) .authorizationCodeServices(authorizationCodeServices) .tokenServices(tokenService) .allowedTokenEndpointRequestMethods(HttpMethod.POST) .exceptionTranslator(new WebResponseTranslator()); } /** * 令牌访问端点安全策略 */ @Override public void configure(AuthorizationServerSecurityConfigurer security) { security .tokenKeyAccess("permitAll()") .checkTokenAccess("permitAll()") .allowFormAuthenticationForClients(); }}
(3) WebSecurityConfig文章源自JAVA秀-https://www.javaxiu.com/66807.html
@Configuration@EnableGlobalMethodSecurity(prePostEnabled = true)public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private SuccessHandler successHandler; @Autowired private FailureHandler failureHandler; @Autowired private LogoutHandler logoutHandler; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().formLogin() .loginProcessingUrl("/login").permitAll() .successHandler(successHandler).permitAll() .failureHandler(failureHandler).permitAll().and() .logout().logoutSuccessHandler(logoutHandler).and() .authorizeRequests() .antMatchers("/**").permitAll(); }}
(4) SecurityUserDetailService文章源自JAVA秀-https://www.javaxiu.com/66807.html
@Service@Slf4jpublic class SecurityUserDetailService implements UserDetailsService { @Autowired private UserService userService; @Autowired private PermissionService permissionService; @Override public UserDetails loadUserByUsername(String username) { UserEntity user = userService.getUserByUsername(username); if (user == null) { return null; } //获取权限 List<PermissionEntry> permissions = permissionService.getPermissionsByUserId(user.getId()); List<String> codes = permissions.stream().map(PermissionEntry::getCode).collect(Collectors.toList()); String[] authorities = null; if (CollectionUtils.isNotEmpty(codes)) { authorities = new String[codes.size()]; codes.toArray(authorities); } //身份令牌 String principal = JSON.toJSONString(user); return User.withUsername(principal).password(user.getPassword()).authorities(authorities).build(); }}
@EnableDiscoveryClient@SpringBootApplicationpublic class UaaApplication { public static void main(String[] args) { SpringApplication.run(UaaApplication.class); }}
4 Gateway服务搭建
文章源自JAVA秀-https://www.javaxiu.com/66807.html
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>demo</artifactId> <groupId>com.rosh</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>gateway</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--授权--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <!--fegin--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>com.rosh</groupId> <artifactId>common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies></project>
server: port: 9000spring: application: name: gateway cloud: nacos: discovery: server-addr: 192.168.226.39:8848 gateway: routes: - id: school-server uri: lb://school-server predicates: - Path=/api/school/** filters: - RewritePath=/api/school/(?<segment>.*),/$\{segment} - id: uaa-server uri: lb://uaa-server predicates: - Path=/api/uaa/** filters: - RewritePath=/api/uaa/(?<segment>.*),/$\{segment}
(1) TokenConfig文章源自JAVA秀-https://www.javaxiu.com/66807.html
@Configurationpublic class TokenConfig { /** * 秘钥串 */ private static final String SIGNING_KEY = "uaa"; @Bean public TokenStore tokenStore() { return new JwtTokenStore(accessTokenConverter()); } @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(SIGNING_KEY); return converter; }}
(2) SecurityConfig文章源自JAVA秀-https://www.javaxiu.com/66807.html
@EnableWebFluxSecurity@Configurationpublic class SecurityConfig { @Bean public SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) { return http.authorizeExchange() .pathMatchers("/**").permitAll() .anyExchange().authenticated() .and().csrf().disable().build(); }}
@Component@Slf4jpublic class GatewayFilterConfig implements GlobalFilter, Ordered { @Autowired private TokenStore tokenStore; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String requestUrl = exchange.getRequest().getPath().value(); AntPathMatcher pathMatcher = new AntPathMatcher(); //1 uaa服务所有放行 if (pathMatcher.match("/api/uaa/**", requestUrl)) { return chain.filter(exchange); } //2 检查token是否存在 String token = getToken(exchange); if (StringUtils.isBlank(token)) { return noTokenMono(exchange); } //3 判断是否是有效的token OAuth2AccessToken oAuth2AccessToken; try { oAuth2AccessToken = tokenStore.readAccessToken(token); Map<String, Object> additionalInformation = oAuth2AccessToken.getAdditionalInformation(); //取出用户身份信息 String principal = MapUtils.getString(additionalInformation, "user_name"); //获取用户权限 List<String> authorities = (List<String>) additionalInformation.get("authorities"); JSONObject jsonObject=new JSONObject(); jsonObject.put("principal",principal); jsonObject.put("authorities",authorities); //给header里面添加值 String base64 = EncryptUtil.encodeUTF8StringBase64(jsonObject.toJSONString()); ServerHttpRequest tokenRequest = exchange.getRequest().mutate().header("json-token", base64).build(); ServerWebExchange build = exchange.mutate().request(tokenRequest).build(); return chain.filter(build); } catch (InvalidTokenException e) { log.info("无效的token: {}", token); return invalidTokenMono(exchange); } } /** * 获取token */ private String getToken(ServerWebExchange exchange) { String tokenStr = exchange.getRequest().getHeaders().getFirst("Authorization"); if (StringUtils.isBlank(tokenStr)) { return null; } String token = tokenStr.split(" ")[1]; if (StringUtils.isBlank(token)) { return null; } return token; } /** * 无效的token */ private Mono<Void> invalidTokenMono(ServerWebExchange exchange) { JSONObject json = new JSONObject(); json.put("status", HttpStatus.UNAUTHORIZED.value()); json.put("data", "无效的token"); return buildReturnMono(json, exchange); } private Mono<Void> noTokenMono(ServerWebExchange exchange) { JSONObject json = new JSONObject(); json.put("status", HttpStatus.UNAUTHORIZED.value()); json.put("data", "没有token"); return buildReturnMono(json, exchange); } private Mono<Void> buildReturnMono(JSONObject json, ServerWebExchange exchange) { ServerHttpResponse response = exchange.getResponse(); byte[] bits = json.toJSONString().getBytes(StandardCharsets.UTF_8); DataBuffer buffer = response.bufferFactory().wrap(bits); response.setStatusCode(HttpStatus.UNAUTHORIZED); //指定编码,否则在浏览器中会中文乱码 response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8"); return response.writeWith(Mono.just(buffer)); } @Override public int getOrder() { return 0; }}
@Configurationpublic class GatewayCorsConfiguration { @Bean public CorsWebFilter corsWebFilter(){ CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**",corsConfiguration); return new CorsWebFilter(source); }}
@SpringBootApplication@EnableDiscoveryClient@EnableFeignClientspublic class GatewayApplicaion { public static void main(String[] args) { SpringApplication.run(GatewayApplicaion.class); }}
5 School微服务
文章源自JAVA秀-https://www.javaxiu.com/66807.html
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>demo</artifactId> <groupId>com.rosh</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>school</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.rosh</groupId> <artifactId>common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--授权--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>
server: port: 8000spring: application: name: school-server cloud: nacos: discovery: server-addr: 192.168.226.39:8848
(1) TokenConfig文章源自JAVA秀-https://www.javaxiu.com/66807.html
@Configurationpublic class TokenConfig { private static final String SIGNING_KEY = "uaa"; @Bean public TokenStore tokenStore() { return new JwtTokenStore(accessTokenConverter()); } @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(SIGNING_KEY); return converter; }}
(2) ResouceServerConfig文章源自JAVA秀-https://www.javaxiu.com/66807.html
@Configuration@EnableResourceServer@EnableGlobalMethodSecurity(prePostEnabled = true)public class ResouceServerConfig extends ResourceServerConfigurerAdapter { @Autowired private TokenStore tokenStore; /** * 资源ID */ private static final String RESOURCE_ID = "res1"; /** * 资源配置 */ @Override public void configure(ResourceServerSecurityConfigurer resources) { resources.resourceId(RESOURCE_ID) .tokenStore(tokenStore) .stateless(true) .accessDeniedHandler(new CustomAccessDeniedHandler()); } /** * 请求配置 */ @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/**").access("#oauth2.hasScope('ROLE_ADMIN')") .and().csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); }}
@Componentpublic class AuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String token = request.getHeader("json-token"); if (StringUtils.isNotBlank(token)){ String json = EncryptUtil.decodeUTF8StringBase64(token); JSONObject jsonObject = JSON.parseObject(json); //获取用户身份信息、权限信息 String principal = jsonObject.getString("principal"); UserEntity user = JSON.parseObject(principal, UserEntity.class); JSONArray tempJsonArray = jsonObject.getJSONArray("authorities"); String[] authorities = tempJsonArray.toArray(new String[0]); //身份信息、权限信息填充到用户身份token对象中 UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(user,null, AuthorityUtils.createAuthorityList(authorities)); //创建details authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); //将authenticationToken填充到安全上下文 SecurityContextHolder.getContext().setAuthentication(authenticationToken); } filterChain.doFilter(request,response); }}
(1) 学生接口文章源自JAVA秀-https://www.javaxiu.com/66807.html
@RestController@RequestMapping("/student")public class StudentController { /** * 老师权限或学生权限 */ @GetMapping("/grade") @PreAuthorize("hasAnyAuthority('teacher','student')") public Object rs(HttpServletRequest request){ Map<String,Object> map=new HashMap<>(); map.put("张三",100); return map; }}
(2) 老师接口文章源自JAVA秀-https://www.javaxiu.com/66807.html
@RestController@RequestMapping("/teacher")public class TeacherController { /** * 老师权限 */ @GetMapping("/math/grade") @PreAuthorize("hasAuthority('teacher')") public Object rs() { List<Map<String, Object>> maps = new ArrayList<>(); for (int i = 1; i <= 10; i++) { Map<String, Object> map = new HashMap<>(); map.put("张三" + i, 100); maps.add(map); } return maps; }}
6 集成测试
{"username":"kakaxi","password":"123","authorities":["student","teacher"]}{"username":"mingren","password":"123","authorities":["student"]}
文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
(1) 申请老师权限token文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
(2) 带着token验证接口文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
(3) 申请学生token文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
(4) 验证token文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
7 Github地址
code、sql脚本文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.htmlhttps://github.com/zhurongsheng666/distributed-security文章源自JAVA秀-https://www.javaxiu.com/66807.html
欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
已在知识星球更新源码解析如下:文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。文章源自JAVA秀-https://www.javaxiu.com/66807.html
提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。文章源自JAVA秀-https://www.javaxiu.com/66807.html
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章源自JAVA秀-https://www.javaxiu.com/66807.html
文章有帮助的话,在看,转发吧。谢谢支持哟 (*^__^*)文章源自JAVA秀-https://www.javaxiu.com/66807.html

评论