From 523a2f847161ef1c0d17eadc43d25959bbd94f42 Mon Sep 17 00:00:00 2001 From: Sheldon Zi Date: Tue, 12 Jan 2021 17:31:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(test):=20=E4=BC=98=E5=8C=96=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 使用RestTemplate改写获取accessToken的方法, accessTokenUri可以使用服务名进行负载均衡 2. 获取用户时, 使用ResourceServerTokenServices.loadAuthentication, 支持ResourceServer(isLocal=true/false)的情况 3. 支持角色权限 --- .../test/WithMockSecurityContextFactory.java | 95 ++++++++++--------- 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/pigx-common/pigx-common-test/src/main/java/com/pig4cloud/pigx/test/WithMockSecurityContextFactory.java b/pigx-common/pigx-common-test/src/main/java/com/pig4cloud/pigx/test/WithMockSecurityContextFactory.java index 0460191c1..07de362bb 100644 --- a/pigx-common/pigx-common-test/src/main/java/com/pig4cloud/pigx/test/WithMockSecurityContextFactory.java +++ b/pigx-common/pigx-common-test/src/main/java/com/pig4cloud/pigx/test/WithMockSecurityContextFactory.java @@ -1,26 +1,25 @@ package com.pig4cloud.pigx.test; -import cn.hutool.http.HttpRequest; -import cn.hutool.json.JSONArray; -import cn.hutool.json.JSONObject; +import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; -import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.util.SpringContextHolder; -import com.pig4cloud.pigx.common.security.service.PigxUser; import com.pig4cloud.pigx.test.annotation.WithMockOAuth2User; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.client.OAuth2ClientContext; import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; -import org.springframework.security.oauth2.provider.token.AccessTokenConverter; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; import org.springframework.security.test.context.support.WithSecurityContextFactory; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; -import java.util.Collection; +import java.nio.charset.StandardCharsets; /** * @author lengleng @@ -32,19 +31,17 @@ public class WithMockSecurityContextFactory implements WithSecurityContextFactor @Override public SecurityContext createSecurityContext(WithMockOAuth2User oAuth2User) { - // 1. 请求认证中心 - JSONObject authResult = request(oAuth2User); + // 1. 请求认证中心获取token + String token = getToken(oAuth2User); - // 2. 解析认证中心返回报文 - PigxUser principal = parse(authResult); + // 2. 解析认证中心返回用户 + OAuth2Authentication authentication = getUser(token); // 3. 构建 oauth2 上下文 SecurityContext context = SecurityContextHolder.createEmptyContext(); - Authentication auth = new UsernamePasswordAuthenticationToken(principal, "N/A", principal.getAuthorities()); - context.setAuthentication(auth); + context.setAuthentication(authentication); // 4. 上下文保存 token - String token = authResult.getStr("access_token"); DefaultOAuth2AccessToken accessToken = new DefaultOAuth2AccessToken(token); OAuth2ClientContext clientContext = SpringContextHolder.getBean(OAuth2ClientContext.class); clientContext.setAccessToken(accessToken); @@ -52,42 +49,50 @@ public class WithMockSecurityContextFactory implements WithSecurityContextFactor } /** - * 请求认证中心 + * 请求认证中心获取token + * * @param oAuth2User 账号、密码 - * @return JSONObject + * @return String token */ - private JSONObject request(WithMockOAuth2User oAuth2User) { + private String getToken(final WithMockOAuth2User oAuth2User) { OAuth2ProtectedResourceDetails clientProperties = SpringContextHolder - .getBean(OAuth2ProtectedResourceDetails.class); + .getBean(OAuth2ProtectedResourceDetails.class); - String result = HttpRequest.post(clientProperties.getAccessTokenUri()) - .basicAuth(clientProperties.getClientId(), clientProperties.getClientSecret()) - .form("username", oAuth2User.username()).form("password", oAuth2User.password()) - .form("grant_type", "password").form("scope", clientProperties.getScope()).execute().body(); + HttpHeaders requestHeaders = new HttpHeaders(); + requestHeaders.set( + HttpHeaders.AUTHORIZATION, + HttpUtil.buildBasicAuth( + clientProperties.getClientId(), clientProperties.getClientSecret(), StandardCharsets.UTF_8 + ) + ); - return JSONUtil.parseObj(result); + MultiValueMap requestBody = new LinkedMultiValueMap<>(); + requestBody.add("username", oAuth2User.username()); + requestBody.add("password", oAuth2User.password()); + requestBody.add("grant_type", "password"); + requestBody.put("scope", clientProperties.getScope()); + + HttpEntity> requestEntity = new HttpEntity<>(requestBody, requestHeaders); + + RestTemplate restTemplate = SpringContextHolder.getBean(RestTemplate.class); + String result = restTemplate.exchange( + clientProperties.getAccessTokenUri(), + HttpMethod.POST, + requestEntity, + String.class + ).getBody(); + return JSONUtil.parseObj(result).getStr("access_token"); } /** - * 请求认证中心 - * @param tokenObj 认证中心返回结果 - * @return 用户信息 + * 使用token 获取用户详情 + * + * @param token token + * @return user详细 */ - private PigxUser parse(JSONObject tokenObj) { - JSONObject userInfo = tokenObj.getJSONObject("user_info"); - - Integer id = userInfo.getInt(SecurityConstants.DETAILS_USER_ID); - Integer deptId = userInfo.getInt(SecurityConstants.DETAILS_DEPT_ID); - String phone = userInfo.getStr(SecurityConstants.DETAILS_PHONE); - String avatar = userInfo.getStr(SecurityConstants.DETAILS_AVATAR); - String username = userInfo.getStr(SecurityConstants.DETAILS_USERNAME); - Integer tenantId = userInfo.getInt(SecurityConstants.DETAILS_TENANT_ID); - JSONArray jsonArray = userInfo.getJSONArray(AccessTokenConverter.AUTHORITIES); - - Collection authorities = AuthorityUtils - .createAuthorityList(jsonArray.toArray(new String[0])); - - return new PigxUser(id, deptId, phone, avatar, tenantId, username, "N/A", true, true, true, true, authorities); + private OAuth2Authentication getUser(final String token) { + ResourceServerTokenServices tokenServices = SpringContextHolder.getBean(ResourceServerTokenServices.class); + return tokenServices.loadAuthentication(token); } }