Browse Source

增加了docker镜像生成功能,并测试了部分jwt代码

verguenza 5 years ago
parent
commit
05c4a83ee6

+ 7 - 0
Dockerfile

@@ -0,0 +1,7 @@
+FROM openjdk:13-jdk-buster
+MAINTAINER czhong
+
+ENTRYPOINT ["java", "-jar","--enable-preview", "/usr/share/manatee.jar"]
+
+ARG JAR_FILE
+ADD target/manatee-1.0.jar /usr/share/manatee.jar

+ 25 - 0
pom.xml

@@ -65,6 +65,23 @@
             <version>1.0</version>
             <version>1.0</version>
         </dependency>
         </dependency>
 
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.auth0</groupId>
+            <artifactId>java-jwt</artifactId>
+            <version>3.10.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-core</artifactId>
+            <version>4.1.0</version>
+        </dependency>
+
     </dependencies>
     </dependencies>
 
 
     <build>
     <build>
@@ -84,6 +101,14 @@
                     <forceJavacCompilerUse>true</forceJavacCompilerUse>
                     <forceJavacCompilerUse>true</forceJavacCompilerUse>
                 </configuration>
                 </configuration>
             </plugin>
             </plugin>
+<!--            <plugin>-->
+<!--                <groupId>org.apache.maven.plugins</groupId>-->
+<!--                <artifactId>maven-surefire-plugin</artifactId>-->
+<!--                <version>3.0.0-M3</version>-->
+<!--                <configuration>-->
+<!--                    <argLine>&#45;&#45;enable-preview</argLine>-->
+<!--                </configuration>-->
+<!--            </plugin>-->
         </plugins>
         </plugins>
     </build>
     </build>
 
 

+ 61 - 0
src/main/java/com/galaxis/manatee/configuration/ManateeSecurity.java

@@ -0,0 +1,61 @@
+package com.galaxis.manatee.configuration;
+
+import com.galaxis.manatee.controller.JwtAuthenticationFilter;
+import com.galaxis.manatee.controller.JwtAuthorizationFilter;
+import com.galaxis.manatee.service.impl.UserDetailsServiceImpl;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.HttpMethod;
+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.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.web.cors.CorsConfiguration;
+import org.springframework.web.cors.CorsConfigurationSource;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+
+import static com.galaxis.manatee.constant.SecurityConstant.GO_CONFIRM;
+import static com.galaxis.manatee.constant.SecurityConstant.SIGN_UP_URL;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 6:12 下午
+ */
+@EnableWebSecurity
+public class ManateeSecurity extends WebSecurityConfigurerAdapter {
+
+    private UserDetailsServiceImpl userDetailsService;
+    private BCryptPasswordEncoder bCryptPasswordEncoder;
+
+    public ManateeSecurity(UserDetailsServiceImpl userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
+        this.userDetailsService = userDetailsService;
+        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
+    }
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.cors().and().csrf().disable().authorizeRequests()
+                .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
+                .antMatchers(HttpMethod.GET,GO_CONFIRM).permitAll()
+                .anyRequest().authenticated()
+                .and()
+                .addFilter(new JwtAuthenticationFilter(authenticationManager()))
+                .addFilter(new JwtAuthorizationFilter(authenticationManager()))
+                // this disables session creation on Spring Security
+                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
+    }
+
+    @Override
+    public void configure(AuthenticationManagerBuilder auth) throws Exception {
+        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
+    }
+
+    @Bean
+    CorsConfigurationSource corsConfigurationSource() {
+        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
+        return source;
+    }
+}

+ 23 - 0
src/main/java/com/galaxis/manatee/configuration/SecurityConfiguration.java

@@ -0,0 +1,23 @@
+package com.galaxis.manatee.configuration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 4:38 下午
+ */
+@Configuration
+public class SecurityConfiguration {
+
+    /**
+     * 密码编码器
+     * @return  spring 密码加密器
+     */
+    @Bean
+    public BCryptPasswordEncoder bCryptPasswordEncoder() {
+        return new BCryptPasswordEncoder();
+    }
+}

+ 35 - 0
src/main/java/com/galaxis/manatee/constant/SecurityConstant.java

@@ -0,0 +1,35 @@
+package com.galaxis.manatee.constant;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 6:02 下午
+ */
+public class SecurityConstant {
+
+    /**
+     * token 有效时长
+     */
+    public static Long EXPIRATION_TIME=86400000L;
+    /**
+     * jwt密钥
+     */
+    public static final String SECRET = "galaxis";
+    /**
+     * token前缀
+     */
+    public static final String TOKEN_PREFIX = "Bearer ";
+    /**
+     * 请求头字段
+     */
+    public static final String HEADER_STRING = "Authorization";
+    /**
+     * 注册地址
+     */
+    public static final String SIGN_UP_URL = "/user/signUp";
+
+    /**
+     * 管理员认证
+     */
+    public static final String GO_CONFIRM="/user/goConfirm";
+}

+ 30 - 0
src/main/java/com/galaxis/manatee/controller/ClawController.java

@@ -0,0 +1,30 @@
+package com.galaxis.manatee.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.context.request.WebRequest;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 3:20 下午
+ */
+@RestController
+@Slf4j
+public class ClawController {
+
+    /**
+     * 接口调用异常
+     * @param exception 系统抛出异常
+     * @param request   客户端请求
+     * @return  返回结果
+     */
+    @ExceptionHandler(value = {Exception.class})
+    public ResponseEntity vehicleNotFound(Exception exception, WebRequest request) {
+        log.warn("异常");
+        return new ResponseEntity(exception, HttpStatus.BAD_REQUEST);
+    }
+}

+ 65 - 0
src/main/java/com/galaxis/manatee/controller/JwtAuthenticationFilter.java

@@ -0,0 +1,65 @@
+package com.galaxis.manatee.controller;
+
+import com.auth0.jwt.JWT;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.galaxis.manatee.constant.SecurityConstant;
+import com.galaxis.manatee.entity.User;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+
+import static com.auth0.jwt.algorithms.Algorithm.HMAC512;
+
+/**
+ * jwt filter for security
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 3:50 下午
+ */
+public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
+
+    private AuthenticationManager authenticationManager;
+
+    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
+        this.authenticationManager = authenticationManager;
+    }
+
+    @Override
+    public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException {
+        try {
+            User user = new ObjectMapper().readValue(req.getInputStream(), User.class);
+
+            return authenticationManager.authenticate(
+                    new UsernamePasswordAuthenticationToken(
+                            user.getUserName(),
+                            user.getPassword(),
+                            new ArrayList<>())
+            );
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    protected void successfulAuthentication(HttpServletRequest req,
+                                            HttpServletResponse res,
+                                            FilterChain chain,
+                                            Authentication auth) throws IOException, ServletException {
+
+        String token = JWT.create()
+                .withSubject(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername())
+                .withExpiresAt(new Date(System.currentTimeMillis() + SecurityConstant.EXPIRATION_TIME))
+                .sign(HMAC512(SecurityConstant.SECRET.getBytes()));
+        res.addHeader(SecurityConstant.HEADER_STRING, SecurityConstant.TOKEN_PREFIX + token);
+    }
+}

+ 70 - 0
src/main/java/com/galaxis/manatee/controller/JwtAuthorizationFilter.java

@@ -0,0 +1,70 @@
+package com.galaxis.manatee.controller;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.galaxis.manatee.constant.SecurityConstant;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import static com.galaxis.manatee.constant.SecurityConstant.HEADER_STRING;
+import static com.galaxis.manatee.constant.SecurityConstant.TOKEN_PREFIX;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 6:00 下午
+ */
+public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
+
+    public JwtAuthorizationFilter(AuthenticationManager authManager) {
+        super(authManager);
+    }
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest req,
+                                    HttpServletResponse res,
+                                    FilterChain chain) throws IOException, ServletException {
+        String header = req.getHeader(HEADER_STRING);
+
+        if (header == null || !header.startsWith(TOKEN_PREFIX)) {
+            chain.doFilter(req, res);
+            return;
+        }
+
+        UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
+
+        SecurityContextHolder.getContext().setAuthentication(authentication);
+        chain.doFilter(req, res);
+    }
+
+    /**
+     * This method reads the JWT from the Authorization header, and then uses JWT to validate the token
+     * @param request   请求
+     * @return  认证的token或者认证失败返回null
+     */
+    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
+        String token = request.getHeader(HEADER_STRING);
+        if (token != null) {
+            // parse the token.
+            String user = JWT.require(Algorithm.HMAC512(SecurityConstant.SECRET.getBytes()))
+                    .build()
+                    .verify(token.replace(TOKEN_PREFIX, ""))
+                    .getSubject();
+
+            if (user != null) {
+                return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
+            }
+            return null;
+        }
+        return null;
+    }
+}

+ 88 - 0
src/main/java/com/galaxis/manatee/controller/UserController.java

@@ -0,0 +1,88 @@
+package com.galaxis.manatee.controller;
+
+import com.aliyuncs.exceptions.ClientException;
+import com.galaxis.manatee.entity.User;
+import com.galaxis.manatee.service.UserService;
+import com.galaxis.manatee.util.AliSmsUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Random;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 4:54 下午
+ */
+@Slf4j
+@RestController
+@RequestMapping("/user")
+public class UserController {
+
+    private UserService userService;
+    private BCryptPasswordEncoder bCryptPasswordEncoder;
+    private String confirmCode;
+
+    /**
+     * 验证人手机号
+     */
+    @Value(("${aliyun.access.mobile}"))
+    private String mobile;
+    /**
+     * 验证key的Id
+     */
+    @Value(("${aliyun.access.key.id}"))
+    private String accessKeyId;
+    /**
+     * 验证key的secret
+     */
+    @Value(("${aliyun.access.key.secret}"))
+    private String accessKeySecret;
+
+    public UserController(UserService userService, BCryptPasswordEncoder bCryptPasswordEncoder) {
+        this.userService = userService;
+        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
+    }
+
+    /**
+     * 异常处理
+     * @param exception 异常
+     * @return  结果
+     */
+    @ExceptionHandler
+    public ResponseEntity<String> exceptionHandler(Exception exception){
+        return new ResponseEntity<>(exception.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR);
+    }
+
+    /**
+     * 管理员认证
+     */
+    @GetMapping("/goConfirm")
+    public void mobileConfirm() throws ClientException {
+        Random random=new Random();
+        String s=String.valueOf(random.nextLong());
+        confirmCode=s.substring(s.length()-6);
+        log.info(confirmCode+"");
+        //发短信
+//        AliSmsUtil.sendRegisterConfirmCode("18088233323",confirmCode,accessKeyId,accessKeySecret);
+    }
+
+    /**
+     * 注册
+     * @param user   应用会员
+     * @return  注册结果
+     */
+    @PostMapping("/signUp")
+    public ResponseEntity<String> signUp(@RequestBody User user) {
+        if(user.getConfirmCode()==null||!user.getConfirmCode().equals(confirmCode)){
+            return new ResponseEntity<>("验证码信息错误", HttpStatus.NON_AUTHORITATIVE_INFORMATION);
+        }
+        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
+        userService.signUp(user);
+        return new ResponseEntity<>(null, HttpStatus.OK);
+    }
+}

+ 21 - 0
src/main/java/com/galaxis/manatee/dao/UserDao.java

@@ -0,0 +1,21 @@
+package com.galaxis.manatee.dao;
+
+import com.galaxis.manatee.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 4:27 下午
+ */
+@Repository
+public interface UserDao extends JpaRepository<User,Long> {
+
+    /**
+     * 根据用户名获取用户
+     * @param userName  用户名
+     * @return  用户对象
+     */
+    User findByUserName(String userName);
+}

+ 41 - 0
src/main/java/com/galaxis/manatee/entity/User.java

@@ -0,0 +1,41 @@
+package com.galaxis.manatee.entity;
+
+import lombok.Data;
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Transient;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 4:23 下午
+ */
+@Entity(name = "USER")
+@Data
+public class User {
+
+    @Id
+    @GeneratedValue(generator = "idGeneratorBasicTrade")
+    @GenericGenerator(name ="idGeneratorBasicTrade" ,strategy="com.galaxis.manatee.util.impl.GalaxisIdGenerator")
+    private Long id;
+
+    /**
+     * 用户名
+     */
+    private String userName;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 验证码
+     */
+    @Transient
+    private String confirmCode;
+
+}

+ 2 - 2
src/main/java/com/galaxis/manatee/service/ChuanyunScheduledTask.java

@@ -60,8 +60,8 @@ public class ChuanyunScheduledTask {
      */
      */
     @Scheduled(fixedDelay = 600000L)
     @Scheduled(fixedDelay = 600000L)
     private void putProcessInstanceToChuanyun(){
     private void putProcessInstanceToChuanyun(){
-        //同步物料补发数据
-        putMaterialResendInstance();
+        //同步物料补发数据,已经停用,数据结构发生变化,请不要使用
+//        putMaterialResendInstance();
     }
     }
 
 
     /**
     /**

+ 17 - 0
src/main/java/com/galaxis/manatee/service/UserService.java

@@ -0,0 +1,17 @@
+package com.galaxis.manatee.service;
+
+import com.galaxis.manatee.entity.User;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 4:55 下午
+ */
+public interface UserService {
+
+    /**
+     * 注册
+     * @param user   用户
+     */
+    void signUp(User user);
+}

+ 33 - 0
src/main/java/com/galaxis/manatee/service/impl/UserDetailsServiceImpl.java

@@ -0,0 +1,33 @@
+package com.galaxis.manatee.service.impl;
+
+import com.galaxis.manatee.dao.UserDao;
+import com.galaxis.manatee.entity.User;
+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.Service;
+
+import static java.util.Collections.emptyList;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 6:16 下午
+ */
+@Service
+public class UserDetailsServiceImpl implements UserDetailsService {
+    private UserDao userDao;
+
+    public UserDetailsServiceImpl(UserDao userDao) {
+        this.userDao = userDao;
+    }
+
+    @Override
+    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
+        User user = userDao.findByUserName(userName);
+        if (user == null) {
+            throw new UsernameNotFoundException(userName);
+        }
+        return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(), emptyList());
+    }
+}

+ 26 - 0
src/main/java/com/galaxis/manatee/service/impl/UserServiceImpl.java

@@ -0,0 +1,26 @@
+package com.galaxis.manatee.service.impl;
+
+import com.galaxis.manatee.dao.UserDao;
+import com.galaxis.manatee.entity.User;
+import com.galaxis.manatee.service.UserService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 4:55 下午
+ */
+@Service
+public class UserServiceImpl implements UserService {
+
+    private UserDao userDao;
+
+    public UserServiceImpl(UserDao userDao) {
+        this.userDao = userDao;
+    }
+
+    @Override
+    public void signUp(User user) {
+        userDao.save(user);
+    }
+}

+ 58 - 0
src/main/java/com/galaxis/manatee/util/AliSmsUtil.java

@@ -0,0 +1,58 @@
+package com.galaxis.manatee.util;
+
+import com.aliyuncs.CommonRequest;
+import com.aliyuncs.CommonResponse;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.http.MethodType;
+import com.aliyuncs.profile.DefaultProfile;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.regex.Pattern;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 5:08 下午
+ */
+@Slf4j
+public class AliSmsUtil {
+
+    /**
+     * 手机号校验正则表达式
+     */
+    private static Pattern mobilePattern=Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$");
+
+    /**
+     * 手机号验证
+     * @param  phoneNumber  手机号码
+     * @return 验证通过返回true
+     */
+    public static boolean isMobile(final String phoneNumber) {
+        return mobilePattern.matcher(phoneNumber).matches();
+    }
+
+    /**
+     * 发送注册认证短信
+     * @param mobile   手机号
+     * @param confirmCode   验证码
+     */
+    public static void sendRegisterConfirmCode(String mobile,String confirmCode,String accessKeyId,String accessSecret) throws ClientException {
+        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessSecret);
+        IAcsClient client = new DefaultAcsClient(profile);
+
+        CommonRequest request = new CommonRequest();
+        request.setMethod(MethodType.POST);
+        request.setDomain("dysmsapi.aliyuncs.com");
+        request.setVersion("2017-05-25");
+        request.setAction("SendSms");
+        request.putQueryParameter("RegionId", "cn-hangzhou");
+        request.putQueryParameter("PhoneNumbers", mobile);
+        request.putQueryParameter("SignName", "");
+        request.putQueryParameter("TemplateCode", "");
+        request.putQueryParameter("TemplateParam", "{\"code\":\""+confirmCode+"\"}");
+        CommonResponse response = client.getCommonResponse(request);
+        log.info(response.getData());
+    }
+}

+ 15 - 0
src/main/java/com/galaxis/manatee/util/impl/JwtUtil.java

@@ -0,0 +1,15 @@
+package com.galaxis.manatee.util.impl;
+
+import org.springframework.beans.factory.annotation.Value;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/3 3:57 下午
+ */
+public class JwtUtil implements Serializable {
+
+}

+ 8 - 1
src/main/resources/application.yml

@@ -27,6 +27,13 @@ dingTalk:
     #物料补发
     #物料补发
     materialResend: PROC-FF6YHERSO2-J9GFWKONMK1QXZH153MV1-4G2HF7VI-2P
     materialResend: PROC-FF6YHERSO2-J9GFWKONMK1QXZH153MV1-4G2HF7VI-2P
 
 
+#阿里云
+aliyun:
+  access:
+    key:
+      id: ${ACCESS_KEY_ID}
+      secret: ${ACCESS_KEY_SECRET}
+    mobile: ${ALIYUN_MOBILE}
 #spring data jpa database
 #spring data jpa database
 spring:
 spring:
   task:
   task:
@@ -35,7 +42,7 @@ spring:
         size: 50
         size: 50
       thread-name-prefix: scheduled-task-
       thread-name-prefix: scheduled-task-
   datasource:
   datasource:
-    url: jdbc:mysql://localhost:3306/manatee?autoReconnect=true&characterEncoding=utf-8
+    url: ${MYSQL_URL}
     username: ${USER_NAME}
     username: ${USER_NAME}
     password: ${PASSWORD}
     password: ${PASSWORD}
   jpa:
   jpa: