Commit 62964b8b authored by Junling Bu's avatar Junling Bu
Browse files

fix[litemall-wx-api,litemall-admin-api]:...

fix[litemall-wx-api,litemall-admin-api]: 采用spring-security的BCryptPasswordEncoder来对用户和管理员密码加密。目前存在问题是,两个模块使用了两次代码。之后可能会实现一个新的litemall-util模块来存放通用类。
parent 3e672d47
package org.linlinjava.litemall.admin.util.bcrypt;
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.security.SecureRandom;
import java.util.regex.Pattern;
/**
* Implementation of PasswordEncoder that uses the BCrypt strong hashing function. Clients
* can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a SecureRandom
* instance. The larger the strength parameter the more work will have to be done
* (exponentially) to hash the passwords. The default value is 10.
*
* @author Dave Syer
*
*/
public class BCryptPasswordEncoder {
private Pattern BCRYPT_PATTERN = Pattern
.compile("\\A\\$2a?\\$\\d\\d\\$[./0-9A-Za-z]{53}");
private final Log logger = LogFactory.getLog(getClass());
private final int strength;
private final SecureRandom random;
public BCryptPasswordEncoder() {
this(-1);
}
/**
* @param strength the log rounds to use, between 4 and 31
*/
public BCryptPasswordEncoder(int strength) {
this(strength, null);
}
/**
* @param strength the log rounds to use, between 4 and 31
* @param random the secure random instance to use
*
*/
public BCryptPasswordEncoder(int strength, SecureRandom random) {
if (strength != -1 && (strength < BCrypt.MIN_LOG_ROUNDS || strength > BCrypt.MAX_LOG_ROUNDS)) {
throw new IllegalArgumentException("Bad strength");
}
this.strength = strength;
this.random = random;
}
public String encode(CharSequence rawPassword) {
String salt;
if (strength > 0) {
if (random != null) {
salt = BCrypt.gensalt(strength, random);
}
else {
salt = BCrypt.gensalt(strength);
}
}
else {
salt = BCrypt.gensalt();
}
return BCrypt.hashpw(rawPassword.toString(), salt);
}
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (encodedPassword == null || encodedPassword.length() == 0) {
logger.warn("Empty encoded password");
return false;
}
if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
logger.warn("Encoded password does not look like BCrypt");
return false;
}
return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ package org.linlinjava.litemall.admin.web;
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
import org.linlinjava.litemall.admin.service.AdminTokenManager;
import org.linlinjava.litemall.admin.util.bcrypt.BCryptPasswordEncoder;
import org.linlinjava.litemall.db.domain.LitemallAdmin;
import org.linlinjava.litemall.db.service.LitemallAdminService;
import org.linlinjava.litemall.db.util.ResponseUtil;
......@@ -66,6 +67,12 @@ public class AdminController {
if(adminId == null){
return ResponseUtil.unlogin();
}
String rawPassword = admin.getPassword();
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode(rawPassword);
admin.setPassword(encodedPassword);
adminService.add(admin);
return ResponseUtil.ok(admin);
}
......
......@@ -5,6 +5,7 @@ import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.admin.dao.AdminToken;
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
import org.linlinjava.litemall.admin.service.AdminTokenManager;
import org.linlinjava.litemall.admin.util.bcrypt.BCryptPasswordEncoder;
import org.linlinjava.litemall.db.domain.LitemallAdmin;
import org.linlinjava.litemall.db.service.LitemallAdminService;
import org.linlinjava.litemall.db.util.JacksonUtil;
......@@ -39,13 +40,18 @@ public class AuthController {
return ResponseUtil.badArgument();
}
List<LitemallAdmin> adminList = adminService.findAdmin(username, password);
List<LitemallAdmin> adminList = adminService.findAdmin(username);
Assert.state(adminList.size() < 2, "同一个用户名存在两个账户");
if(adminList.size() == 0){
return ResponseUtil.badArgumentValue();
}
LitemallAdmin admin = adminList.get(0);
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
if(!encoder.matches(password, admin.getPassword())){
return ResponseUtil.fail(403, "账号密码不对");
}
Integer adminId = admin.getId();
// token
AdminToken adminToken = AdminTokenManager.generateToken(adminId);
......
package org.linlinjava.litemall.admin;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.linlinjava.litemall.admin.util.bcrypt.BCryptPasswordEncoder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class BcryptTest {
@Test
public void test() {
String rawPassword = "aaaaaa";
String encodedPassword ="";
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
encodedPassword = bCryptPasswordEncoder.encode(rawPassword);
System.out.println("rawPassword=" + rawPassword + " encodedPassword=" + encodedPassword);
Assert.assertTrue(bCryptPasswordEncoder.matches(rawPassword, encodedPassword));
}
}
......@@ -16,9 +16,9 @@ public class LitemallAdminService {
@Resource
private LitemallAdminMapper adminMapper;
public List<LitemallAdmin> findAdmin(String username, String password) {
public List<LitemallAdmin> findAdmin(String username) {
LitemallAdminExample example = new LitemallAdminExample();
example.or().andUsernameEqualTo(username).andPasswordEqualTo(password);
example.or().andUsernameEqualTo(username);
return adminMapper.selectByExample(example);
}
......
package org.linlinjava.litemall.wx.util.bcrypt;
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.security.SecureRandom;
import java.util.regex.Pattern;
/**
* Implementation of PasswordEncoder that uses the BCrypt strong hashing function. Clients
* can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a SecureRandom
* instance. The larger the strength parameter the more work will have to be done
* (exponentially) to hash the passwords. The default value is 10.
*
* @author Dave Syer
*
*/
public class BCryptPasswordEncoder {
private Pattern BCRYPT_PATTERN = Pattern
.compile("\\A\\$2a?\\$\\d\\d\\$[./0-9A-Za-z]{53}");
private final Log logger = LogFactory.getLog(getClass());
private final int strength;
private final SecureRandom random;
public BCryptPasswordEncoder() {
this(-1);
}
/**
* @param strength the log rounds to use, between 4 and 31
*/
public BCryptPasswordEncoder(int strength) {
this(strength, null);
}
/**
* @param strength the log rounds to use, between 4 and 31
* @param random the secure random instance to use
*
*/
public BCryptPasswordEncoder(int strength, SecureRandom random) {
if (strength != -1 && (strength < BCrypt.MIN_LOG_ROUNDS || strength > BCrypt.MAX_LOG_ROUNDS)) {
throw new IllegalArgumentException("Bad strength");
}
this.strength = strength;
this.random = random;
}
public String encode(CharSequence rawPassword) {
String salt;
if (strength > 0) {
if (random != null) {
salt = BCrypt.gensalt(strength, random);
}
else {
salt = BCrypt.gensalt(strength);
}
}
else {
salt = BCrypt.gensalt();
}
return BCrypt.hashpw(rawPassword.toString(), salt);
}
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (encodedPassword == null || encodedPassword.length() == 0) {
logger.warn("Empty encoded password");
return false;
}
if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
logger.warn("Encoded password does not look like BCrypt");
return false;
}
return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
}
}
\ No newline at end of file
......@@ -14,6 +14,7 @@ import org.linlinjava.litemall.wx.dao.UserInfo;
import org.linlinjava.litemall.wx.dao.UserToken;
import org.linlinjava.litemall.wx.service.UserTokenManager;
import org.linlinjava.litemall.wx.util.IpUtil;
import org.linlinjava.litemall.wx.util.bcrypt.BCryptPasswordEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
......@@ -60,8 +61,9 @@ public class WxAuthController {
user = userList.get(0);
}
if(!user.getPassword().equals(password)){
return ResponseUtil.badArgumentValue();
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
if(!encoder.matches(password, user.getPassword())){
return ResponseUtil.fail(403, "账号密码不对");
}
// userInfo
......@@ -168,11 +170,15 @@ public class WxAuthController {
if(userList.size() > 0){
return ResponseUtil.fail(403, "手机号已注册");
}
LitemallUser user = new LitemallUser();
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode(password);
user.setPassword(encodedPassword);
user = new LitemallUser();
user.setUsername(username);
user.setPassword(password);
user.setPassword(encodedPassword);
user.setMobile(mobile);
user.setWeixinOpenid("");
user.setAvatar("https://yanxuan.nosdn.127.net/80841d741d7fa3073e0ae27bf487339f.jpg?imageView&quality=90&thumbnail=64x64");
......@@ -225,7 +231,10 @@ public class WxAuthController {
user = userList.get(0);
}
user.setPassword(password);
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode(password);
user.setPassword(encodedPassword);
userService.update(user);
return ResponseUtil.ok();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment