基于OAuth2.0+JWT的鉴权中心(下——资源中心配置)
在上一讲中我们讲了认证中心配置我们也成为了认证服务器,本篇文章我们主要来配置一下资源中心配置,也叫资源服务器,同时做一下测试。
一)创建项目
下面进行资源服务器app-customer-login模块的配置。
B、app-customer-login创建
这个模块主要是
1、创建一个新的模块,和前面几讲的一样,打开上一篇创建的项目microservice选中,并单击右键New→Module,选择Spring Initializr默认下一步;
2、进入该页面填Group和Artifact,Group要写对和上次的要一样,Artifact 我命名为app-customer-login,如图1所示:
3、点击Next,选择相关依赖,Spring Cloud Security 下的Cloud OAuth2是核心依赖如下图2所示:
4、继续Next→Finish,等待下载依赖。完成后,首先进行启动类AppCustomerLoginApplication的配置,如下图3所示:
5、配置application.properties,如下图所示:
由于排版问题,我下面代码里面做下注解:
# 注册服务中心配置
server.port=8201
spring.application.name=app-customer-login
eureka.client.service-url.defaultZone: http://localhost:8081/eureka/
feign.sentinel.enabled=true
# sentinel dashboard
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.main.allow-bean-definition-overriding=true
# Mysql配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springauth?serverTimezone=UTC&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=glen1996
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
# OAuth2.0配置
# 该地址会获取public key ye也就是我们在认证服务器中配置的内容
security.oauth2.resource.jwt.key-uri=http://localhost:8085/oauth/token_key
# 在认证服务器中配置的客户端的id
security.oauth2.client.client-id=user-service
# 在认证服务器中配置的resources的id
security.oauth2.resource.id=user-service
# 在认证服务器中配置的客户端的密码
security.oauth2.client.client-secret=123456
# 获取令牌的地址
security.oauth2.client.access-token-uri=http://localhost:8085/oauth/token
# 在认证服务器中配置的客户端的授权类型
security.oauth2.client.grant-type=password
# 在认证服务器中配置的客户端的授权范围
security.oauth2.client.scope=service
# 通过授权码方式传递授权码
security.oauth2.client.user-authorization-uri=http://localhost:8085/oauth/authorize
6、接下来我们新建六个文件夹,如下图所示:
7、在service中新建三个类AuthServiceClient、UserRepository和UserServiceDetail。
(1)、AuthServiceClient.java
这是一个负载类,主要是映射认证中心的/oauth/token类,获取令牌,当出现问题时可以fallback。内容如下:
代码如下:
@FeignClient(value = "auth-server", fallback = AuthServiceClientFallback.class)
public interface AuthServiceClient {
@PostMapping("/oauth/token")
JWT getToken(@RequestHeader("Authorization") String Authorization,
@RequestParam("grant_type") String grant_type,
@RequestParam("username") String username,
@RequestParam("password") String password);
}
(2)、UserRepository.java
这个在认证服务器模块已经写过了,是一样的,内容如下:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
(3)、UserServiceDetail.java
这块内容主要是很多实现方法:
@Service
@Slf4j
public class UserServiceDetail {
@Autowired
private UserRepository userRepository;
@Autowired
private OAuth2ClientProperties oAuth2ClientProperties;
@Autowired
OAuth2ProtectedResourceDetails oAuth2ProtectedResourceDetails;
@Autowired
UserServiceDetail userServiceDetail;
@Value("${security.oauth2.client.access-token-uri}")
String accessTokenUri;
@Autowired
private RestTemplate restTemplate;
@Autowired
private AuthServiceClient client;
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// 注册用户
public User insertUser(String username, String password){
User user=new User();
user.setUsername(username);
user.setPassword(BPwdEncoderUtil.BCryptPassword(password));
return userRepository.save(user);
}
//登录获取access_token
public ResponseEntity<OAuth2AccessToken> login(@Valid User loginDto,BindingResult bindingResult,HttpServletResponse response) throws Exception{
if (bindingResult.hasErrors()) {
throw new Exception("登录信息错误,请确认后再试");
}
log.info(loginDto.getUsername()+"---"+loginDto.getPassword());
User user = userRepository.findByUsername(loginDto.getUsername());
if (null == user) {
throw new Exception("用户为空,出错了");
}
if (!BPwdEncoderUtil.matches(loginDto.getPassword(), user.getPassword().replace("{bcrypt}",""))) {
throw new Exception("密码不正确");
}
String client_secret =oAuth2ClientProperties.getClientId()+":"+oAuth2ClientProperties.getClientSecret();
client_secret = "Basic "+Base64.getEncoder().encodeToString(client_secret.getBytes());
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Authorization",client_secret);
//授权请求信息
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.put("username", Collections.singletonList(loginDto.getUsername()));
map.put("password", Collections.singletonList(loginDto.getPassword()));
map.put("grant_type", Collections.singletonList(oAuth2ProtectedResourceDetails.getGrantType()));
map.put("scope", oAuth2ProtectedResourceDetails.getScope());
//HttpEntity
HttpEntity httpEntity = new HttpEntity(map,httpHeaders);
//获取 Token
log.info("client_secret:"+client_secret+"loginDto.getUsername:"+loginDto.getUsername()+"--loginDto.getUsername:"+loginDto.getPassword()+"123:"+oAuth2ProtectedResourceDetails.getAccessTokenUri()+"httpEntity:"+httpEntity+"OAuth2AccessToken.class:"+OAuth2AccessToken.class);
//第一种方式获取jwt
// 从auth-service获取JWT
JWT jwt = client.getToken(client_secret, "password", loginDto.getUsername(), loginDto.getPassword());
log.info("jwt----"+jwt);
//第二种方式获取
ResponseEntity<OAuth2AccessToken> re =restTemplate.exchange(oAuth2ProtectedResourceDetails.getAccessTokenUri(), HttpMethod.POST,httpEntity,OAuth2AccessToken.class);
if (re.getStatusCode() != HttpStatus.OK) {
log.debug("failed to authenticate user with OAuth2 token endpoint, status: {}",
re.getStatusCodeValue());
throw new HttpClientErrorException(re.getStatusCode());
}
OAuth2AccessToken oAuth2AccessToken = re.getBody();
log.info("re----"+re);
log.info("re12----"+restTemplate.exchange(accessTokenUri, HttpMethod.POST,httpEntity,OAuth2AccessToken.class));
return restTemplate.exchange(accessTokenUri, HttpMethod.POST,httpEntity,OAuth2AccessToken.class);
}
}
核心代码还是 登录获取access_token这一块,包含了两部分用户密码验证和授权信息请求两部分。如果要用第一种方式获取JWT,就需要配置service中的AuthServiceClient.java这个文件。
8、实现AuthServiceClient.java 中的getToken()方法,所以在com.glen.appcustomerlogin.service.impl中创建AuthServiceClientFallback.java文件。
内容如下:
代码如下:
@Slf4j
@Component
public class AuthServiceClientFallback implements AuthServiceClient {
@Override
public JWT getToken(String Authorization,
String grant_type,
String username,
String password) {
log.info("您获取令牌失败了哦,请稍后重试");
return null;
}
}
9、在com.glen.appcustomerlogin.exception中创建ExceptionHandler、UserLoginException两个异常处理类,只写一部分代码,后面大家可以根据自己需求做拓展。
A、ExceptionHandler.java
@ControllerAdvice
@ResponseBody
public class ExceptionHandler {
@org.springframework.web.bind.annotation.ExceptionHandler(value = UserLoginException.class)
public ResponseEntity<String> handleException(Exception e) {
return new ResponseEntity(e.getMessage(), HttpStatus.OK);
}
}
B、UserLoginException.java
public class UserLoginException extends RuntimeException {
public UserLoginException(String message) {
super(message);
}
}
10、在com.glen.appcustomerlogin.entity中创建四个文件,其中两个User和Role这两个文件可以从认证中心copy过来,改一下包名就行。另外两个类需要新建,分别为JWT和UserLoginDTO
A、JWT.java
这是一个JWT的实体类,jwt返回的字段应该包含这些内容,具体如下:
代码如下:
@Data
public class JWT {
private String access_token;
private String token_type;
private String refresh_token;
private int expires_in;
private String scope;
private String jti;
}
@data这个注解很方便推荐大家使用,可以避免写get、set语句。
B、UserLoginDTO.java
这是一个UserLoginDTO的实体类,主要是包含了JWT和User两个对象,具体如下:
代码如下:
@Data
public class UserLoginDTO {
private JWT jwt;
private User user;
}
11、在com.glen.appcustomerlogin.controller下,创建测试登录入口AppcustomerLoginController.java文件
内容如下:
代码如下:
@RequestMapping("/user")
@RestController
@Slf4j
public class AppcustomerLoginController {
@Autowired
UserServiceDetail userServiceDetail;
@RequestMapping("/login")
public ResponseEntity<OAuth2AccessToken> login(@Valid User loginDto, BindingResult bindingResult,HttpServletResponse response) throws Exception {
return userServiceDetail.login(loginDto,bindingResult,response);
}
@PostMapping("/register")
public User postUser(@RequestParam("username") String username,
@RequestParam("password") String password) {
return userServiceDetail.insertUser(username, password);
}
@RequestMapping("/foo")
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
public String getFoo() {
return "程序猿小哥哥,你的鉴权测试通过啦";
}
}
一共三个方法,登录、注册以及一个权限测试方法。
12、在com.glen.appcustomerlogin.entity中创建三个文件:
BPwdEncoderUtil、JwtConfig和ResourceServerConfig。
A、BPwdEncoderUtil.java
该class主要的作用还是进行编码,内容如下:
代码如下:
public class BPwdEncoderUtil{
private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
public static String BCryptPassword(String password){
return encoder.encode(password);
}
public static boolean matches(CharSequence rawPassword, String encodedPassword){
return encoder.matches(rawPassword,encodedPassword);
}
}
B、JwtConfig.java
这个类这要有两个方法,一个方法tokenStore()主要是用来获取并存储tokenStore,另一个方法jwtTokenEnhancer(),主要是获取publicKey,我们上一讲讲过对称加密和非对称加密,这一块主要是设置资源服务器的publicKey,当用户请求时用该key和鉴权服务器的test-jwt.jks做权限验证。同时,我们将上节课生成的public.cert文件迁移到resources下面
代码如下:
@Slf4j
@Configuration
@EnableAuthorizationServer
public class JwtConfig {
public static final String public_cert = "public.cert";
@Bean
@Qualifier("tokenStore")
public TokenStore tokenStore() {
return new JwtTokenStore(jwtTokenEnhancer());
}
@Bean
protected JwtAccessTokenConverter jwtTokenEnhancer() {
// converter.setSigningKey("123");
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
Resource resource = new ClassPathResource(public_cert);
String publicKey;
try {
publicKey = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
}catch (IOException e) {
throw new RuntimeException(e);
}
converter.setVerifierKey(publicKey);
log.info("public key:"+converter);
return converter;
}
}
C、ResourceServerConfig.java
这一块有两个方法:
configure(HttpSecurity http):主要是做权限,即允许哪些页面不通过鉴权就能访问。
configure(ResourceServerSecurityConfigurer resources):主要是做两方面的事情,第一设置tokenStore,也就是publicKey,第二是设置该资源的id。
@Configuration
@EnableResourceServer
@EnableOAuth2Client
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/oauth/**","/oauth/token", "/user/login","/user/register").permitAll()
.antMatchers("/**").authenticated();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore).resourceId("user-service");
}
}
二)测试项目
1、首先我们先导入数据库如下内容:
/*
Navicat MySQL Data Transfer
Source Server : localhost_3306
Source Server Type : MySQL
Source Server Version : 80016
Source Host : localhost:3306
Source Schema : springauth
Target Server Type : MySQL
Target Server Version : 80016
File Encoding : 65001
Date: 01/08/2019 09:31:42
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for clientdetails
-- ----------------------------
DROP TABLE IF EXISTS `clientdetails`;
CREATE TABLE `clientdetails` (
`appId` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`resourceIds` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`appSecret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`grantTypes` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`redirectUrl` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`access_token_validity` int(11) NULL DEFAULT NULL,
`refresh_token_validity` int(11) NULL DEFAULT NULL,
`additionalInformation` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`autoApproveScopes` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`appId`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for oauth_access_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_access_token`;
CREATE TABLE `oauth_access_token` (
`token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`token` blob NULL,
`authentication_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`user_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`authentication` blob NULL,
`refresh_token` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`authentication_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for oauth_approvals
-- ----------------------------
DROP TABLE IF EXISTS `oauth_approvals`;
CREATE TABLE `oauth_approvals` (
`userId` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`clientId` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`status` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`expiresAt` datetime(0) NULL DEFAULT NULL,
`lastModifiedAt` datetime(0) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for oauth_client_details
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details` (
`client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`access_token_validity` int(11) NULL DEFAULT NULL,
`refresh_token_validity` int(11) NULL DEFAULT NULL,
`additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`client_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of oauth_client_details
-- ----------------------------
INSERT INTO `oauth_client_details` VALUES ('client_1', NULL, '$2a$10$pejbmDk1wAg28dVKCzEA7eMDMXaOQzo0jOMqoZwSkY2NWapwkQZJq', 'select', 'refresh_token,client_credentials,password', NULL, 'oauth2', NULL, NULL, NULL, NULL);
INSERT INTO `oauth_client_details` VALUES ('client_2', NULL, '$2a$10$pejbmDk1wAg28dVKCzEA7eMDMXaOQzo0jOMqoZwSkY2NWapwkQZJq', 'server', 'refresh_token,password', NULL, 'oauth2', NULL, NULL, NULL, NULL);
INSERT INTO `oauth_client_details` VALUES ('user-service', 'user-service', '$2a$10$pejbmDk1wAg28dVKCzEA7eMDMXaOQzo0jOMqoZwSkY2NWapwkQZJq', 'service', 'refresh_token,password', 'http://localhost:8765/store/home', 'ROLE_ADMIN,ROLE_DEVICE,ROLE_VIDEO', 3600, 7200, NULL, 'true');
-- ----------------------------
-- Table structure for oauth_client_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_token`;
CREATE TABLE `oauth_client_token` (
`token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`token` blob NULL,
`authentication_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`user_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`authentication_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for oauth_code
-- ----------------------------
DROP TABLE IF EXISTS `oauth_code`;
CREATE TABLE `oauth_code` (
`code` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`authentication` blob NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for oauth_refresh_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_refresh_token`;
CREATE TABLE `oauth_refresh_token` (
`token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`token` blob NULL,
`authentication` blob NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES (1, 'ROLE_ADMIN');
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `UK_sb8bbouer5wak8vyiiy4pf2bx`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '$2a$10$zaLf6sSbWTaNoBsHEQFUm.Ad3cZxutkYo16yqA7IC7rNIPzbQ8cFe', 'glen');
INSERT INTO `user` VALUES (13, '$2a$10$3.GxfWHLkolVgMtTT/Pz0ed8qlTxLQo97KDIWVR/t7V4B2F2AbKma', 'test');
INSERT INTO `user` VALUES (14, '$2a$10$pejbmDk1wAg28dVKCzEA7eMDMXaOQzo0jOMqoZwSkY2NWapwkQZJq', 'user-service');
-- ----------------------------
-- Table structure for user_role
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
`user_id` bigint(20) NOT NULL,
`role_id` bigint(20) NOT NULL,
INDEX `FKa68196081fvovjhkek5m97n3y`(`role_id`) USING BTREE,
INDEX `FK859n2jvi8ivhui0rl0esws6o`(`user_id`) USING BTREE,
CONSTRAINT `FK859n2jvi8ivhui0rl0esws6o` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `FKa68196081fvovjhkek5m97n3y` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES (1, 1);
SET FOREIGN_KEY_CHECKS = 1;
2、我们依次启动EurekaServerApplication、AuthorizationServerApplication以及AppCustomerLoginApplication。如果有报数据库错误,注意修改配置文件中的数据库配置。
3、以下为项目中的所有端口的清单:
8081:Eureka注册中心
8082:config-bus-server
8083:config-bus-client
8084:gateway-server
8085:authorization-server
8086:app-server-login
8100:app-server-first
8101:app-server-second
8200:app-customer-first
8201:app-customer-login
4、我们用Postman做测试,首先注册一个用户,命令如下:
http://localhost:8201/user/register?password=123456&username=test
返回结果如图:
说明我们注册成功了。
5、通过登录接口获取token。
我们访问如下地址:用户名和密码就是我们刚才注册的。
http://localhost:8201/user/login?password=123456&username=test
内容如下,因为postman的问题没有显示,但是我们可以在控制台看得到内容:
控制台内容如下所示:
不论是jwt还是re或是re12,里面的access_token都是可以的。
得到如下:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidXNlci1zZXJ2aWNlIl0sImV4cCI6MTU2NDYzODExNCwidXNlcl9uYW1lIjoidGVzdCIsImp0aSI6IjIxN2I4MDA4LTQxODAtNGJhMS1iOGE5LTc4OWQyNjkzNzg0OSIsImNsaWVudF9pZCI6InVzZXItc2VydmljZSIsInNjb3BlIjpbInNlcnZpY2UiXX0.fUi9URxXAhO9aNEkak9MVKHtVoIMAg2wUnMV1Zgzph3kGBP_lsTfKDDDOLFF8hAtxGHBJEjBVZAhE2nBTOC7C-vNFZJLwU6kOBkrc5WvkTKDzl3Uw3qMJzR6ugUELqlQv60iLFShBnT1MbKgPmxBiF0-wqtxBC2oxqpldi_w2zNv9snhY76vveBspGnQNe5MIaU1uXApExtN3nDknfQzDfMMW5YB9pycIVKPaeszyt4G4hgExUvymVnw7OyVGUfuhpbiNI0r-ttKIrkEj1YmlXd9BfC_FK4oHY_Ad1nZfZzsZLyfhLstHyUZdW2yvKfsPB6BdSwdSxRjYevNmXxfBg
6、接下来我们先不带token访问http://localhost:8201/user/foo会发现报
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
说明没有权限访问。接下来我们携带token访问。
http://localhost:8201/user/foo?access_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidXNlci1zZXJ2aWNlIl0sImV4cCI6MTU2NDYzODExNCwidXNlcl9uYW1lIjoidGVzdCIsImp0aSI6IjIxN2I4MDA4LTQxODAtNGJhMS1iOGE5LTc4OWQyNjkzNzg0OSIsImNsaWVudF9pZCI6InVzZXItc2VydmljZSIsInNjb3BlIjpbInNlcnZpY2UiXX0.fUi9URxXAhO9aNEkak9MVKHtVoIMAg2wUnMV1Zgzph3kGBP_lsTfKDDDOLFF8hAtxGHBJEjBVZAhE2nBTOC7C-vNFZJLwU6kOBkrc5WvkTKDzl3Uw3qMJzR6ugUELqlQv60iLFShBnT1MbKgPmxBiF0-wqtxBC2oxqpldi_w2zNv9snhY76vveBspGnQNe5MIaU1uXApExtN3nDknfQzDfMMW5YB9pycIVKPaeszyt4G4hgExUvymVnw7OyVGUfuhpbiNI0r-ttKIrkEj1YmlXd9BfC_FK4oHY_Ad1nZfZzsZLyfhLstHyUZdW2yvKfsPB6BdSwdSxRjYevNmXxfBg
会发现不允许访问,因为我们在之前的controller里面设置了一段代码:
@RequestMapping("/foo")
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
public String getFoo() {
return "程序猿小哥哥,你的鉴权测试通过啦";
}
这个地方的@PreAuthorize(“hasAuthority(‘ROLE_ADMIN’)”)表示哪些角色可以访问,很明显可以看到"ROLE_ADMIN"这个角色可以访问,因此我们需要添加用户和对应的角色关系。
7、打开user表,查看test的id,我的为16
8、然后打开role表,查看ROLE_ADMIN的id为1
9、最后打开user_role表,添加对应的id,如图所示,点击提交。
10、再次重复5、6步骤,结果如下图,说明测试通过。