fix: LDAP用户登录问题

This commit is contained in:
shiziyuan9527 2020-07-14 17:28:53 +08:00
parent f6e30833de
commit 0c9badda9c
6 changed files with 87 additions and 49 deletions

View File

@ -1,23 +1,13 @@
package io.metersphere.controller; package io.metersphere.controller;
import io.metersphere.base.domain.UserRole; import io.metersphere.commons.constants.UserSource;
import io.metersphere.controller.request.LoginRequest; import io.metersphere.controller.request.LoginRequest;
import io.metersphere.dto.UserDTO;
import io.metersphere.i18n.Translator;
import io.metersphere.service.UserService; import io.metersphere.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
import static io.metersphere.commons.constants.SessionConstants.ATTR_USER;
@RestController @RestController
@RequestMapping @RequestMapping
@ -36,6 +26,7 @@ public class LoginController {
@PostMapping(value = "/signin") @PostMapping(value = "/signin")
public ResultHolder login(@RequestBody LoginRequest request) { public ResultHolder login(@RequestBody LoginRequest request) {
SecurityUtils.getSubject().getSession().setAttribute("authenticate", UserSource.LOCAL.name());
return userService.login(request); return userService.login(request);
} }

View File

@ -9,12 +9,12 @@ import io.metersphere.controller.request.LoginRequest;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import io.metersphere.ldap.domain.Person; import io.metersphere.ldap.domain.Person;
import io.metersphere.ldap.service.LdapService; import io.metersphere.ldap.service.LdapService;
import io.metersphere.ldap.domain.LdapInfo;
import io.metersphere.service.SystemParameterService; import io.metersphere.service.SystemParameterService;
import io.metersphere.service.UserService; import io.metersphere.service.UserService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
@RestController @RestController
@ -38,10 +38,9 @@ public class LdapController {
Person person = ldapService.authenticate(request); Person person = ldapService.authenticate(request);
SecurityUtils.getSubject().getSession().setAttribute("authenticate", "ldap"); SecurityUtils.getSubject().getSession().setAttribute("authenticate", UserSource.LDAP.name());
String username = request.getUsername(); String username = request.getUsername();
String password = request.getPassword();
String email = person.getEmail(); String email = person.getEmail();
@ -55,19 +54,15 @@ public class LdapController {
user.setId(username); user.setId(username);
user.setName(username); user.setName(username);
user.setEmail(email); user.setEmail(email);
user.setPassword(password);
user.setSource(UserSource.LDAP.name()); user.setSource(UserSource.LDAP.name());
userService.addLdapUser(user); userService.addLdapUser(user);
} else {
request.setUsername(u.getId());
request.setPassword(u.getPassword());
} }
return userService.login(request); return userService.login(request);
} }
@PostMapping("/test/connect") @PostMapping("/test/connect")
public void testConnect(@RequestBody LdapInfo ldapInfo) { public void testConnect() {
ldapService.testConnect(); ldapService.testConnect();
} }

View File

@ -2,6 +2,7 @@ package io.metersphere.security;
import io.metersphere.base.domain.Role; import io.metersphere.base.domain.Role;
import io.metersphere.commons.constants.UserSource;
import io.metersphere.commons.user.SessionUser; import io.metersphere.commons.user.SessionUser;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.dto.UserDTO; import io.metersphere.dto.UserDTO;
@ -64,10 +65,69 @@ public class ShiroDBRealm extends AuthorizingRealm {
@Override @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String login = (String) SecurityUtils.getSubject().getSession().getAttribute("authenticate");
String userId = token.getUsername(); String userId = token.getUsername();
String password = String.valueOf(token.getPassword()); String password = String.valueOf(token.getPassword());
if (StringUtils.equals("local", runMode)) {
UserDTO user = getUserWithOutAuthenticate(userId);
userId = user.getId();
SessionUser sessionUser = SessionUser.fromUser(user);
SessionUtils.putUser(sessionUser);
return new SimpleAuthenticationInfo(userId, password, getName());
}
if (StringUtils.equals(login, UserSource.LOCAL.name())) {
return loginLocalMode(userId, password);
}
if (StringUtils.equals(login, UserSource.LDAP.name())) {
return loginLdapMode(userId, password);
}
UserDTO user = getUserWithOutAuthenticate(userId);
userId = user.getId();
SessionUser sessionUser = SessionUser.fromUser(user);
SessionUtils.putUser(sessionUser);
return new SimpleAuthenticationInfo(userId, password, getName());
}
private UserDTO getUserWithOutAuthenticate(String userId) {
UserDTO user = userService.getUserDTO(userId); UserDTO user = userService.getUserDTO(userId);
String msg; String msg;
if (user == null) {
user = userService.getUserDTOByEmail(userId);
if (user == null) {
msg = "The user does not exist: " + userId;
logger.warn(msg);
throw new UnknownAccountException(Translator.get("user_not_exist") + userId);
}
}
return user;
}
private AuthenticationInfo loginLdapMode(String userId, String password) {
UserDTO user = userService.getLoginUser(userId, UserSource.LDAP.name());
String msg;
if (user == null) {
msg = "The user does not exist: " + userId;
logger.warn(msg);
throw new UnknownAccountException(Translator.get("user_not_exist") + userId);
}
userId = user.getId();
SessionUser sessionUser = SessionUser.fromUser(user);
SessionUtils.putUser(sessionUser);
return new SimpleAuthenticationInfo(userId, password, getName());
}
private AuthenticationInfo loginLocalMode(String userId, String password) {
UserDTO user = userService.getLoginUser(userId, UserSource.LOCAL.name());
String msg;
if (user == null) { if (user == null) {
user = userService.getUserDTOByEmail(userId); user = userService.getUserDTOByEmail(userId);
if (user == null) { if (user == null) {
@ -77,27 +137,6 @@ public class ShiroDBRealm extends AuthorizingRealm {
} }
userId = user.getId(); userId = user.getId();
} }
// local test
if (StringUtils.equals("local", runMode)) {
SessionUser sessionUser = SessionUser.fromUser(user);
SessionUtils.putUser(sessionUser);
return new SimpleAuthenticationInfo(userId, password, getName());
}
// apikey 校验不验证密码
if (ApiKeySessionHandler.random.equalsIgnoreCase(password)) {
SessionUser sessionUser = SessionUser.fromUser(user);
SessionUtils.putUser(sessionUser);
return new SimpleAuthenticationInfo(userId, password, getName());
}
String login = (String) SecurityUtils.getSubject().getSession().getAttribute("authenticate");
if (StringUtils.equals(login, "ldap")) {
SessionUser sessionUser = SessionUser.fromUser(user);
SessionUtils.putUser(sessionUser);
return new SimpleAuthenticationInfo(userId, password, getName());
}
// 密码验证 // 密码验证
if (!userService.checkUserPassword(userId, password)) { if (!userService.checkUserPassword(userId, password)) {
throw new IncorrectCredentialsException(Translator.get("password_is_incorrect")); throw new IncorrectCredentialsException(Translator.get("password_is_incorrect"));

View File

@ -180,6 +180,15 @@ public class UserService {
return userDTO; return userDTO;
} }
public UserDTO getLoginUser(String userId, String source) {
UserExample example = new UserExample();
example.createCriteria().andIdEqualTo(userId).andSourceEqualTo(source);
if (userMapper.countByExample(example) == 0) {
return null;
}
return getUserDTO(userId);
}
public UserDTO getUserDTOByEmail(String email) { public UserDTO getUserDTOByEmail(String email) {
UserExample example = new UserExample(); UserExample example = new UserExample();
example.createCriteria().andEmailEqualTo(email); example.createCriteria().andEmailEqualTo(email);
@ -487,11 +496,15 @@ public class UserService {
} }
public ResultHolder login(LoginRequest request) { public ResultHolder login(LoginRequest request) {
String login = (String) SecurityUtils.getSubject().getSession().getAttribute("authenticate");
String msg; String msg;
String username = StringUtils.trim(request.getUsername()); String username = StringUtils.trim(request.getUsername());
String password = StringUtils.trim(request.getPassword()); String password = "";
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { if (!StringUtils.equals(login, UserSource.LDAP.name())) {
return ResultHolder.error("user or password can't be null"); password = StringUtils.trim(request.getPassword());
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
return ResultHolder.error("user or password can't be null");
}
} }
UsernamePasswordToken token = new UsernamePasswordToken(username, password); UsernamePasswordToken token = new UsernamePasswordToken(username, password);

View File

@ -199,7 +199,7 @@
initTableData() { initTableData() {
this.result = this.$get("/user/info/" + this.currentUser().id, response => { this.result = this.$get("/user/info/" + this.currentUser().id, response => {
let data = response.data; let data = response.data;
this.isLdapUser = response.data.source === 'Ldap' ? true : false; this.isLdapUser = response.data.source === 'LDAP' ? true : false;
let dataList = []; let dataList = [];
dataList[0] = data; dataList[0] = data;
this.tableData = dataList; this.tableData = dataList;

View File

@ -17,8 +17,8 @@
<div class="form"> <div class="form">
<el-form-item v-slot:default> <el-form-item v-slot:default>
<el-radio-group v-model="form.authenticate"> <el-radio-group v-model="form.authenticate">
<el-radio label="ldap" size="mini">LDAP</el-radio> <el-radio label="LDAP" size="mini">LDAP</el-radio>
<el-radio label="normal" size="mini">普通登录</el-radio> <el-radio label="LOCAL" size="mini">普通登录</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item prop="username"> <el-form-item prop="username">
@ -69,7 +69,7 @@
form: { form: {
username: '', username: '',
password: '', password: '',
authenticate: 'normal' authenticate: 'LOCAL'
}, },
rules: { rules: {
username: [ username: [
@ -115,10 +115,10 @@
this.$refs[form].validate((valid) => { this.$refs[form].validate((valid) => {
if (valid) { if (valid) {
switch (this.form.authenticate) { switch (this.form.authenticate) {
case "normal": case "LOCAL":
this.normalLogin(); this.normalLogin();
break; break;
case "ldap": case "LDAP":
this.ldapLogin(); this.ldapLogin();
break; break;
default: default: