refactor: 适配cas
This commit is contained in:
parent
6e7fe725a1
commit
064304ba28
|
@ -272,6 +272,24 @@
|
|||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- buji-pac4j -->
|
||||
<dependency>
|
||||
<groupId>org.pac4j</groupId>
|
||||
<artifactId>pac4j-cas</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.buji</groupId>
|
||||
<artifactId>buji-pac4j</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>shiro-web</artifactId>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
public enum OssMode {
|
||||
CAS,LOCAL
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import org.apache.shiro.cache.CacheManager;
|
||||
import org.apache.shiro.session.mgt.SessionManager;
|
||||
import org.apache.shiro.web.servlet.Cookie;
|
||||
import org.apache.shiro.web.servlet.SimpleCookie;
|
||||
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ShiroUtils {
|
||||
|
||||
public static void loadBaseFilterChain(Map<String, String> filterChainDefinitionMap){
|
||||
|
||||
filterChainDefinitionMap.put("/resource/**", "anon");
|
||||
filterChainDefinitionMap.put("/signin", "anon");
|
||||
filterChainDefinitionMap.put("/ldap/signin", "anon");
|
||||
filterChainDefinitionMap.put("/ldap/open", "anon");
|
||||
filterChainDefinitionMap.put("/isLogin", "anon");
|
||||
filterChainDefinitionMap.put("/css/**", "anon");
|
||||
filterChainDefinitionMap.put("/js/**", "anon");
|
||||
filterChainDefinitionMap.put("/img/**", "anon");
|
||||
filterChainDefinitionMap.put("/fonts/**", "anon");
|
||||
|
||||
// for swagger
|
||||
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
|
||||
filterChainDefinitionMap.put("/swagger-ui/**", "anon");
|
||||
filterChainDefinitionMap.put("/v3/api-docs/**", "anon");
|
||||
|
||||
filterChainDefinitionMap.put("/403", "anon");
|
||||
filterChainDefinitionMap.put("/anonymous/**", "anon");
|
||||
}
|
||||
|
||||
public static Cookie getSessionIdCookie(){
|
||||
SimpleCookie sessionIdCookie = new SimpleCookie();
|
||||
sessionIdCookie.setPath("/");
|
||||
sessionIdCookie.setName("MS_SESSION_ID");
|
||||
return sessionIdCookie;
|
||||
}
|
||||
|
||||
public static SessionManager getSessionManager(Long sessionTimeout, CacheManager cacheManager){
|
||||
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
|
||||
sessionManager.setSessionIdUrlRewritingEnabled(false);
|
||||
sessionManager.setDeleteInvalidSessions(true);
|
||||
sessionManager.setSessionValidationSchedulerEnabled(true);
|
||||
sessionManager.setSessionIdCookie(ShiroUtils.getSessionIdCookie());
|
||||
sessionManager.setGlobalSessionTimeout(sessionTimeout * 1000);// 超时时间ms
|
||||
sessionManager.setCacheManager(cacheManager);
|
||||
|
||||
//sessionManager.setSessionIdCookieEnabled(true);
|
||||
return sessionManager;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.config;
|
||||
|
||||
import io.metersphere.commons.utils.ShiroUtils;
|
||||
import io.metersphere.security.ApiKeyFilter;
|
||||
import io.metersphere.security.LoginFilter;
|
||||
import io.metersphere.security.ShiroDBRealm;
|
||||
|
@ -9,9 +10,8 @@ import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
|||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||
import org.apache.shiro.web.servlet.SimpleCookie;
|
||||
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
|
@ -29,6 +29,7 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix="oss",name = "mode", havingValue = "local", matchIfMissing = true)
|
||||
public class ShiroConfig implements EnvironmentAware {
|
||||
private Environment env;
|
||||
|
||||
|
@ -42,26 +43,8 @@ public class ShiroConfig implements EnvironmentAware {
|
|||
shiroFilterFactoryBean.setSuccessUrl("/");
|
||||
|
||||
shiroFilterFactoryBean.getFilters().put("apikey", new ApiKeyFilter());
|
||||
|
||||
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
||||
filterChainDefinitionMap.put("/resource/**", "anon");
|
||||
filterChainDefinitionMap.put("/", "anon");
|
||||
filterChainDefinitionMap.put("/signin", "anon");
|
||||
filterChainDefinitionMap.put("/ldap/signin", "anon");
|
||||
filterChainDefinitionMap.put("/ldap/open", "anon");
|
||||
filterChainDefinitionMap.put("/isLogin", "anon");
|
||||
filterChainDefinitionMap.put("/css/**", "anon");
|
||||
filterChainDefinitionMap.put("/js/**", "anon");
|
||||
filterChainDefinitionMap.put("/img/**", "anon");
|
||||
filterChainDefinitionMap.put("/fonts/**", "anon");
|
||||
|
||||
// for swagger
|
||||
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
|
||||
filterChainDefinitionMap.put("/swagger-ui/**", "anon");
|
||||
filterChainDefinitionMap.put("/v3/api-docs/**", "anon");
|
||||
|
||||
filterChainDefinitionMap.put("/403", "anon");
|
||||
filterChainDefinitionMap.put("/anonymous/**", "anon");
|
||||
ShiroUtils.loadBaseFilterChain(filterChainDefinitionMap);
|
||||
filterChainDefinitionMap.put("/**", "apikey, authc");
|
||||
return shiroFilterFactoryBean;
|
||||
}
|
||||
|
@ -120,18 +103,7 @@ public class ShiroConfig implements EnvironmentAware {
|
|||
@Bean
|
||||
public SessionManager sessionManager(MemoryConstrainedCacheManager memoryConstrainedCacheManager) {
|
||||
Long sessionTimeout = env.getProperty("session.timeout", Long.class, 1800L); // 默认1800s, 半个小时
|
||||
|
||||
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
|
||||
sessionManager.setSessionIdUrlRewritingEnabled(false);
|
||||
sessionManager.setGlobalSessionTimeout(sessionTimeout * 1000);// 超时时间ms
|
||||
sessionManager.setDeleteInvalidSessions(true);
|
||||
sessionManager.setSessionValidationSchedulerEnabled(true);
|
||||
SimpleCookie sessionIdCookie = new SimpleCookie();
|
||||
sessionManager.setSessionIdCookie(sessionIdCookie);
|
||||
sessionIdCookie.setPath("/");
|
||||
sessionIdCookie.setName("MS_SESSION_ID");
|
||||
sessionManager.setCacheManager(memoryConstrainedCacheManager);
|
||||
return sessionManager;
|
||||
return ShiroUtils.getSessionManager(sessionTimeout, memoryConstrainedCacheManager);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.controller;
|
||||
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -22,4 +23,15 @@ public class IndexController {
|
|||
return "redirect:/";
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(value = "/oss/login")
|
||||
public String ossLogin() {
|
||||
return "redirect:/";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/oss/logout")
|
||||
public void ossLogout() {
|
||||
SecurityUtils.getSubject().logout();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
package io.metersphere.controller;
|
||||
|
||||
import io.metersphere.commons.constants.OssMode;
|
||||
import io.metersphere.commons.constants.UserSource;
|
||||
import io.metersphere.commons.user.SessionUser;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.LoginRequest;
|
||||
import io.metersphere.service.UserService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -15,11 +20,21 @@ public class LoginController {
|
|||
|
||||
@Resource
|
||||
private UserService userService;
|
||||
@Resource
|
||||
private Environment env;
|
||||
|
||||
@GetMapping(value = "/isLogin")
|
||||
public ResultHolder isLogin() {
|
||||
if (SecurityUtils.getSubject().isAuthenticated()) {
|
||||
return ResultHolder.success(LocaleContextHolder.getLocale());
|
||||
SessionUser user = SessionUtils.getUser();
|
||||
if (StringUtils.isBlank(user.getLanguage())) {
|
||||
user.setLanguage(LocaleContextHolder.getLocale().toString());
|
||||
}
|
||||
return ResultHolder.success(user);
|
||||
}
|
||||
String ossMode = env.getProperty("oss.mode");
|
||||
if (ossMode != null && StringUtils.equalsIgnoreCase(OssMode.CAS.name(), ossMode)) {
|
||||
return ResultHolder.error("oss");
|
||||
}
|
||||
return ResultHolder.error("");
|
||||
}
|
||||
|
@ -30,9 +45,19 @@ public class LoginController {
|
|||
return userService.login(request);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/currentUser")
|
||||
public ResultHolder currentUser() {
|
||||
return ResultHolder.success(SecurityUtils.getSubject().getSession().getAttribute("user"));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/signout")
|
||||
public ResultHolder logout() {
|
||||
String ossMode = env.getProperty("oss.mode");
|
||||
if (ossMode != null && StringUtils.equalsIgnoreCase(OssMode.CAS.name(), ossMode)) {
|
||||
return ResultHolder.error("oss");
|
||||
} else {
|
||||
SecurityUtils.getSubject().logout();
|
||||
}
|
||||
return ResultHolder.success("");
|
||||
}
|
||||
|
||||
|
@ -42,5 +67,4 @@ public class LoginController {
|
|||
return userService.getDefaultLanguage();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.dto;
|
||||
|
||||
import io.metersphere.base.domain.Role;
|
||||
import io.metersphere.base.domain.User;
|
||||
import io.metersphere.base.domain.UserRole;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
@ -10,28 +11,7 @@ import java.util.List;
|
|||
|
||||
@Getter
|
||||
@Setter
|
||||
public class UserDTO {
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String email;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String status;
|
||||
|
||||
private String source;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
private Long updateTime;
|
||||
|
||||
private String language;
|
||||
|
||||
private String lastWorkspaceId;
|
||||
|
||||
private String lastOrganizationId;
|
||||
public class UserDTO extends User {
|
||||
|
||||
private List<Role> roles = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -49,15 +49,16 @@ public class ShiroDBRealm extends AuthorizingRealm {
|
|||
*/
|
||||
@Override
|
||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||
String userId = (String) principals.getPrimaryPrincipal();
|
||||
return getAuthorizationInfo(userId, userService);
|
||||
}
|
||||
|
||||
String userName = (String) principals.getPrimaryPrincipal();
|
||||
public static AuthorizationInfo getAuthorizationInfo(String userId, UserService userService) {
|
||||
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
|
||||
|
||||
// roles 内容填充
|
||||
UserDTO userDTO = userService.getUserDTO(userName);
|
||||
UserDTO userDTO = userService.getUserDTO(userId);
|
||||
Set<String> roles = userDTO.getRoles().stream().map(Role::getId).collect(Collectors.toSet());
|
||||
authorizationInfo.setRoles(roles);
|
||||
|
||||
return authorizationInfo;
|
||||
}
|
||||
|
||||
|
@ -148,7 +149,6 @@ public class ShiroDBRealm extends AuthorizingRealm {
|
|||
if (!userService.checkUserPassword(userId, password)) {
|
||||
throw new IncorrectCredentialsException(Translator.get("password_is_incorrect"));
|
||||
}
|
||||
//
|
||||
SessionUser sessionUser = SessionUser.fromUser(user);
|
||||
SessionUtils.putUser(sessionUser);
|
||||
return new SimpleAuthenticationInfo(userId, password, getName());
|
||||
|
|
|
@ -163,6 +163,17 @@ public class UserService {
|
|||
userMapper.insertSelective(user);
|
||||
}
|
||||
|
||||
public void createOssUser(User user) {
|
||||
user.setCreateTime(System.currentTimeMillis());
|
||||
user.setUpdateTime(System.currentTimeMillis());
|
||||
user.setStatus(UserStatus.NORMAL);
|
||||
if (StringUtils.isBlank(user.getEmail())) {
|
||||
user.setEmail(user.getId() + "@metershpere.io");
|
||||
}
|
||||
userMapper.insertSelective(user);
|
||||
}
|
||||
|
||||
|
||||
private void checkEmailIsExist(String email) {
|
||||
UserExample userExample = new UserExample();
|
||||
UserExample.Criteria criteria = userExample.createCriteria();
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
import MsUser from "./components/common/head/HeaderUser";
|
||||
import MsHeaderOrgWs from "./components/common/head/HeaderOrgWs";
|
||||
import MsLanguageSwitch from "./components/common/head/LanguageSwitch";
|
||||
import {saveLocalStorage} from "../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
|
@ -36,7 +37,8 @@
|
|||
beforeCreate() {
|
||||
this.$get("/isLogin").then(response => {
|
||||
if (response.data.success) {
|
||||
this.$setLang(response.data.data);
|
||||
this.$setLang(response.data.data.language);
|
||||
saveLocalStorage(response.data);
|
||||
this.auth = true;
|
||||
} else {
|
||||
window.location.href = "/login"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<script>
|
||||
import {getCurrentUser} from "../../../../common/js/utils";
|
||||
import AboutUs from "./AboutUs";
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
name: "MsUser",
|
||||
|
@ -35,7 +36,17 @@
|
|||
this.$router.push('/setting/personsetting').catch(error => error);
|
||||
break;
|
||||
case "logout":
|
||||
this.$get("/signout", function () {
|
||||
axios.get("/signout").then(response => {
|
||||
if (response.data.success) {
|
||||
localStorage.clear();
|
||||
window.location.href = "/login";
|
||||
} else {
|
||||
if (response.data.message === 'oss') {
|
||||
localStorage.clear();
|
||||
window.location.href = "/oss/logout"
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
localStorage.clear();
|
||||
window.location.href = "/login";
|
||||
});
|
||||
|
|
|
@ -88,8 +88,15 @@
|
|||
beforeCreate() {
|
||||
this.$get("/isLogin").then(response => {
|
||||
if (!response.data.success) {
|
||||
this.ready = true;
|
||||
if (response.data.message === 'oss') {
|
||||
window.location.href = "/oss/login"
|
||||
} else {
|
||||
this.ready = true;
|
||||
}
|
||||
} else {
|
||||
let user = response.data.data;
|
||||
saveLocalStorage(user);
|
||||
this.getLanguage(user.language);
|
||||
window.location.href = "/"
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue