Commit 662ce3b484c3726369e4cf6b70fc875e57d2f66e
Committed by
GitHub
Merge pull request #84 from lawrencehj/wvp-28181-2.0
修改用户密码前先验证旧密码,增加安全性
Showing
8 changed files
with
41 additions
and
31 deletions
src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java
| ... | ... | @@ -7,7 +7,6 @@ import org.springframework.security.core.AuthenticationException; |
| 7 | 7 | import org.springframework.security.web.AuthenticationEntryPoint; |
| 8 | 8 | import org.springframework.stereotype.Component; |
| 9 | 9 | |
| 10 | -import javax.servlet.ServletException; | |
| 11 | 10 | import javax.servlet.http.HttpServletRequest; |
| 12 | 11 | import javax.servlet.http.HttpServletResponse; |
| 13 | 12 | import java.io.IOException; | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/DefaultUserDetailsServiceImpl.java
| ... | ... | @@ -7,17 +7,12 @@ import com.github.xiaoymin.knife4j.core.util.StrUtil; |
| 7 | 7 | import org.slf4j.Logger; |
| 8 | 8 | import org.slf4j.LoggerFactory; |
| 9 | 9 | import org.springframework.beans.factory.annotation.Autowired; |
| 10 | -import org.springframework.security.core.CredentialsContainer; | |
| 11 | -import org.springframework.security.core.GrantedAuthority; | |
| 12 | -import org.springframework.security.core.SpringSecurityCoreVersion; | |
| 13 | 10 | import org.springframework.security.core.userdetails.UserDetails; |
| 14 | 11 | import org.springframework.security.core.userdetails.UserDetailsService; |
| 15 | 12 | import org.springframework.security.core.userdetails.UsernameNotFoundException; |
| 16 | 13 | import org.springframework.stereotype.Component; |
| 17 | -import org.springframework.stereotype.Service; | |
| 18 | 14 | |
| 19 | 15 | import java.time.LocalDateTime; |
| 20 | -import java.util.Collection; | |
| 21 | 16 | |
| 22 | 17 | /** |
| 23 | 18 | * 用户登录认证逻辑 |
| ... | ... | @@ -39,12 +34,12 @@ public class DefaultUserDetailsServiceImpl implements UserDetailsService { |
| 39 | 34 | |
| 40 | 35 | // 查出密码 |
| 41 | 36 | User user = userService.getUserByUsername(username); |
| 42 | - String password = SecurityUtils.encryptPassword(user.getPassword()); | |
| 43 | - user.setPassword(password); | |
| 44 | 37 | if (user == null) { |
| 45 | 38 | logger.info("登录用户:{} 不存在", username); |
| 46 | 39 | throw new UsernameNotFoundException("登录用户:" + username + " 不存在"); |
| 47 | 40 | } |
| 41 | + String password = SecurityUtils.encryptPassword(user.getPassword()); | |
| 42 | + user.setPassword(password); | |
| 48 | 43 | return new LoginUser(user, LocalDateTime.now()); |
| 49 | 44 | } |
| 50 | 45 | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/SecurityUtils.java
| 1 | 1 | package com.genersoft.iot.vmp.conf.security; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.conf.security.dto.LoginUser; |
| 4 | -import com.genersoft.iot.vmp.storager.dao.dto.User; | |
| 5 | -import gov.nist.javax.sip.address.UserInfo; | |
| 6 | 4 | import org.springframework.security.authentication.AuthenticationManager; |
| 7 | 5 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
| 8 | 6 | import org.springframework.security.core.Authentication; | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/UserMapper.java
src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java
| ... | ... | @@ -3,16 +3,13 @@ package com.genersoft.iot.vmp.vmanager.user; |
| 3 | 3 | import com.genersoft.iot.vmp.conf.security.SecurityUtils; |
| 4 | 4 | import com.genersoft.iot.vmp.conf.security.dto.LoginUser; |
| 5 | 5 | import com.genersoft.iot.vmp.service.IUserService; |
| 6 | -import com.genersoft.iot.vmp.storager.dao.dto.User; | |
| 7 | 6 | import io.swagger.annotations.Api; |
| 8 | 7 | import io.swagger.annotations.ApiImplicitParam; |
| 9 | 8 | import io.swagger.annotations.ApiImplicitParams; |
| 10 | 9 | import io.swagger.annotations.ApiOperation; |
| 11 | 10 | import org.springframework.beans.factory.annotation.Autowired; |
| 12 | -import org.springframework.beans.factory.annotation.Value; | |
| 13 | 11 | import org.springframework.security.authentication.AuthenticationManager; |
| 14 | 12 | import org.springframework.util.DigestUtils; |
| 15 | -import org.springframework.util.StringUtils; | |
| 16 | 13 | import org.springframework.web.bind.annotation.*; |
| 17 | 14 | |
| 18 | 15 | import javax.security.sasl.AuthenticationException; |
| ... | ... | @@ -53,17 +50,26 @@ public class UserController { |
| 53 | 50 | @ApiOperation("修改密码") |
| 54 | 51 | @ApiImplicitParams({ |
| 55 | 52 | @ApiImplicitParam(name = "username", value = "用户名", dataTypeClass = String.class), |
| 56 | - @ApiImplicitParam(name = "password", value = "密码(未md5加密的密码)", dataTypeClass = String.class), | |
| 53 | + @ApiImplicitParam(name = "oldpassword", value = "旧密码(已md5加密的密码)", dataTypeClass = String.class), | |
| 54 | + @ApiImplicitParam(name = "password", value = "新密码(未md5加密的密码)", dataTypeClass = String.class), | |
| 57 | 55 | }) |
| 58 | 56 | @PostMapping("/changePassword") |
| 59 | - public String changePassword(String password){ | |
| 57 | + public String changePassword(String oldpassword, String password){ | |
| 60 | 58 | // 获取当前登录用户id |
| 61 | - int userId = SecurityUtils.getUserId(); | |
| 62 | - boolean result = userService.changePassword(userId, DigestUtils.md5DigestAsHex(password.getBytes())); | |
| 63 | - if (result) { | |
| 64 | - return "success"; | |
| 65 | - }else { | |
| 66 | - return "fail"; | |
| 59 | + String username = SecurityUtils.getUserInfo().getUsername(); | |
| 60 | + LoginUser user = null; | |
| 61 | + try { | |
| 62 | + user = SecurityUtils.login(username, oldpassword, authenticationManager); | |
| 63 | + if (user != null) { | |
| 64 | + int userId = SecurityUtils.getUserId(); | |
| 65 | + boolean result = userService.changePassword(userId, DigestUtils.md5DigestAsHex(password.getBytes())); | |
| 66 | + if (result) { | |
| 67 | + return "success"; | |
| 68 | + } | |
| 69 | + } | |
| 70 | + } catch (AuthenticationException e) { | |
| 71 | + e.printStackTrace(); | |
| 67 | 72 | } |
| 73 | + return "fail"; | |
| 68 | 74 | } |
| 69 | 75 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/web/AuthController.java
| ... | ... | @@ -3,8 +3,6 @@ package com.genersoft.iot.vmp.web; |
| 3 | 3 | import com.genersoft.iot.vmp.service.IUserService; |
| 4 | 4 | import com.genersoft.iot.vmp.storager.dao.dto.User; |
| 5 | 5 | import org.springframework.beans.factory.annotation.Autowired; |
| 6 | -import org.springframework.beans.factory.annotation.Value; | |
| 7 | -import org.springframework.util.StringUtils; | |
| 8 | 6 | import org.springframework.web.bind.annotation.*; |
| 9 | 7 | |
| 10 | 8 | @CrossOrigin | ... | ... |
web_src/src/components/Login.vue
web_src/src/components/dialog/changePassword.vue
| ... | ... | @@ -11,6 +11,9 @@ |
| 11 | 11 | > |
| 12 | 12 | <div id="shared" style="margin-right: 20px;"> |
| 13 | 13 | <el-form ref="passwordForm" :rules="rules" status-icon label-width="80px"> |
| 14 | + <el-form-item label="旧密码" prop="oldPassword" > | |
| 15 | + <el-input v-model="oldPassword" autocomplete="off"></el-input> | |
| 16 | + </el-form-item> | |
| 14 | 17 | <el-form-item label="新密码" prop="newPassword" > |
| 15 | 18 | <el-input v-model="newPassword" autocomplete="off"></el-input> |
| 16 | 19 | </el-form-item> |
| ... | ... | @@ -31,15 +34,23 @@ |
| 31 | 34 | </template> |
| 32 | 35 | |
| 33 | 36 | <script> |
| 37 | +import crypto from 'crypto' | |
| 34 | 38 | export default { |
| 35 | 39 | name: "changePassword", |
| 36 | 40 | props: {}, |
| 37 | 41 | computed: {}, |
| 38 | 42 | created() {}, |
| 39 | 43 | data() { |
| 40 | - let validatePass = (rule, value, callback) => { | |
| 44 | + let validatePass0 = (rule, value, callback) => { | |
| 45 | + if (value === '') { | |
| 46 | + callback(new Error('请输入旧密码')); | |
| 47 | + } else { | |
| 48 | + callback(); | |
| 49 | + } | |
| 50 | + }; | |
| 51 | + let validatePass1 = (rule, value, callback) => { | |
| 41 | 52 | if (value === '') { |
| 42 | - callback(new Error('请输入密码')); | |
| 53 | + callback(new Error('请输入新密码')); | |
| 43 | 54 | } else { |
| 44 | 55 | if (this.confirmPassword !== '') { |
| 45 | 56 | this.$refs.passwordForm.validateField('confirmPassword'); |
| ... | ... | @@ -57,12 +68,14 @@ export default { |
| 57 | 68 | } |
| 58 | 69 | }; |
| 59 | 70 | return { |
| 71 | + oldPassword: null, | |
| 60 | 72 | newPassword: null, |
| 61 | 73 | confirmPassword: null, |
| 62 | 74 | showDialog: false, |
| 63 | 75 | isLoging: false, |
| 64 | 76 | rules: { |
| 65 | - newPassword: [{ required: true, validator: validatePass, trigger: "blur" }], | |
| 77 | + oldPassword: [{ required: true, validator: validatePass0, trigger: "blur" }], | |
| 78 | + newPassword: [{ required: true, validator: validatePass1, trigger: "blur" }], | |
| 66 | 79 | confirmPassword: [{ required: true, validator: validatePass2, trigger: "blur" }], |
| 67 | 80 | }, |
| 68 | 81 | }; |
| ... | ... | @@ -76,13 +89,14 @@ export default { |
| 76 | 89 | method: 'post', |
| 77 | 90 | url:"/api/user/changePassword", |
| 78 | 91 | params: { |
| 92 | + oldpassword: crypto.createHash('md5').update(this.oldPassword, "utf8").digest('hex'), | |
| 79 | 93 | password: this.newPassword |
| 80 | 94 | } |
| 81 | 95 | }).then((res)=> { |
| 82 | 96 | if (res.data === "success"){ |
| 83 | 97 | this.$message({ |
| 84 | 98 | showClose: true, |
| 85 | - message: '修改成功,请重新登陆', | |
| 99 | + message: '修改成功,请重新登录', | |
| 86 | 100 | type: 'success' |
| 87 | 101 | }); |
| 88 | 102 | this.showDialog = false; |
| ... | ... | @@ -99,8 +113,9 @@ export default { |
| 99 | 113 | }, |
| 100 | 114 | close: function () { |
| 101 | 115 | this.showDialog = false; |
| 102 | - this.newPassword= null; | |
| 103 | - this.confirmPassword=null; | |
| 116 | + this.oldPassword = null; | |
| 117 | + this.newPassword = null; | |
| 118 | + this.confirmPassword = null; | |
| 104 | 119 | }, |
| 105 | 120 | }, |
| 106 | 121 | }; | ... | ... |