add:增加IDM单点登录及修改服务认证

This commit is contained in:
2510220824
2021-09-28 18:13:27 +08:00
parent e405a811b8
commit 8e8bb38d07
19 changed files with 364 additions and 987 deletions
@@ -4,6 +4,7 @@ import com.adc.da.exception.AdcDaBaseException;
import com.adc.da.http.ResponseMessage;
import com.adc.da.http.ResponseMessageCodeEnum;
import com.adc.da.http.Result;
import com.adc.da.login.exception.TokenRuntimeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
@@ -1,41 +0,0 @@
package com.adc.da.main.advice;
import com.adc.da.http.ResponseMessage;
import com.adc.da.http.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
@Slf4j
@ControllerAdvice
@Order(value=2)
public class ShiroExceptionAdvice {
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler({AuthenticationException.class, UnknownAccountException.class,
UnauthenticatedException.class, IncorrectCredentialsException.class})
@ResponseBody
public ResponseMessage unauthorized(Exception exception) {
log.warn(exception.getMessage(), exception);
log.info("catch UnknownAccountException");
return Result.error("A404", "无权访问");
}
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(UnauthorizedException.class)
@ResponseBody
public ResponseMessage unauthorized1(UnauthorizedException exception) {
log.warn(exception.getMessage(), exception);
return Result.error("A404","无权访问");
}
}
@@ -1,44 +0,0 @@
package com.adc.da.main.config;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* shiro 自定义URL规则设置
*/
public class DefinitionUrlConfig {
/**
* 匿名用户,无需登录
*/
private static final String ANON = "anon";
// 拦截器
//rest:比如/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[usermethod] ,其中method为postgetdelete等。
//port:比如/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal//serverName8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
//perms:比如/admins/user/**=perms[useradd*],perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,比如/admins/user/**=perms["useradd*,usermodify*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
//roles:比如/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,比如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。//要实现or的效果看http://zgzty.blog.163.com/blog/static/83831226201302983358670/
//anon:比如/admins/**=anon 没有参数,表示可以匿名使用。
//authc:比如/admins/user/**=authc表示需要认证才能使用,没有参数
//authcBasic:比如/admins/user/**=authcBasic没有参数表示httpBasic认证
//ssl:比如/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
//user:比如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
public static Map<String,String> definitionUrlOptions(){
Map<String, String> filterRuleMap = new LinkedHashMap<>();
//TODO 此处设置URL过滤规则 默认是全部请求进行拦截,此处设置为不拦截的URL地址
filterRuleMap.put("/api/login",ANON);//登录接口
// swagger接口文档
filterRuleMap.put("/v2/api-docs", "anon");
filterRuleMap.put("/webjars/**", "anon");
filterRuleMap.put("/swagger-resources/**", "anon");
filterRuleMap.put("/swagger-ui.html", "anon");
filterRuleMap.put("/doc.html", "anon");
return filterRuleMap;
}
}
@@ -1,151 +0,0 @@
package com.adc.da.main.config;
import com.adc.da.login.security.JWTFilter;
import com.adc.da.login.security.JWTRealm;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
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.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.ClassPathResource;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;
@Configuration
@Order(value=1)
public class ShiroConfig {
private static final String JWT_FILTER_NAME = "jwt";
private static final String URL_SUFFIX="/api";
/**
* 自定义realm,实现登录授权流程
* @return
*/
@Bean(name="jwtRealm")
public JWTRealm jwtRealm() {
return new JWTRealm();
}
/**
* 配置securityManager 管理subject(默认),并把自定义realm交由manager
*/
@Bean
public DefaultSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置realm.
securityManager.setRealm(jwtRealm());
//注入缓存管理器
securityManager.setCacheManager(ehCacheManager());
/*
* 关闭shiro自带的session,详情见文档
* http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
*/
DefaultSubjectDAO defaultSubjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator storageEvaluator = new DefaultSessionStorageEvaluator();
storageEvaluator.setSessionStorageEnabled(false);
defaultSubjectDAO.setSessionStorageEvaluator(storageEvaluator);
securityManager.setSubjectDAO(defaultSubjectDAO);
return securityManager;
}
/**
* 拦截链
*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setFilters(filterMap());
shiroFilterFactoryBean.setFilterChainDefinitionMap(definitionMap());
return shiroFilterFactoryBean;
}
/**
* 自定义拦截器,处理所有请求
*/
private Map<String, Filter> filterMap() {
Map<String, Filter> filterMap = new HashMap<>();
filterMap.put(JWT_FILTER_NAME, new JWTFilter());
return filterMap;
}
/**
* url拦截规则
*/
private Map<String, String> definitionMap() {
// 拦截器
//rest:比如/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[usermethod] ,其中method为postgetdelete等。
//port:比如/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal//serverName8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
//perms:比如/admins/user/**=perms[useradd*],perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,比如/admins/user/**=perms["useradd*,usermodify*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
//roles:比如/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,比如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。//要实现or的效果看http://zgzty.blog.163.com/blog/static/83831226201302983358670/
//anon:比如/admins/**=anon 没有参数,表示可以匿名使用。
//authc:比如/admins/user/**=authc表示需要认证才能使用,没有参数
//authcBasic:比如/admins/user/**=authcBasic没有参数表示httpBasic认证
//ssl:比如/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
//user:比如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
Map<String, String> definitionMap = DefinitionUrlConfig.definitionUrlOptions();
// definitionMap.put(URL_SUFFIX+"/**", JWT_FILTER_NAME);
return definitionMap;
}
/* *//**
* 开启注解
*//*
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
// 强制使用cglib代理,防止和aop冲突
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}*/
/**
* 开启shiro aop注解支持. 使用代理方式; 所以需要开启代码支持;
*
* @param securityManager 安全管理器
* @return 授权Advisor
*/
@Bean("authorizationAttributeSourceAdvisor")
public AuthorizationAttributeSourceAdvisor advisor(DefaultSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
/**
* shiro缓存管理器;
* 需要注入对应的其它的实体类中:
* 1、安全管理器:securityManager
* 可见securityManager是整个shiro的核心;
*
* @return
*/
@Bean
public EhCacheManager ehCacheManager() {
EhCacheManager cacheManager = new EhCacheManager();
cacheManager.setCacheManagerConfigFile("classpath:cache/ehcache.xml");
return cacheManager;
}
}
@@ -1,92 +0,0 @@
package com.adc.da.main.config;
import com.adc.da.login.security.JWTRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.io.ClassPathResource;
//@Configuration
public class ShiroConfiguration {
@Bean(name = "ehCacheManagerFactoryBean")
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
ClassPathResource classPathResource = new ClassPathResource("cache/ehcache-local.xml");
ehCacheManagerFactoryBean.setConfigLocation(classPathResource);
return ehCacheManagerFactoryBean;
}
@Bean(name = "shiroCacheManager")
@DependsOn({ "ehCacheManagerFactoryBean" })
public EhCacheManager shiroCacheManager() {
EhCacheManager ehCacheManager = new EhCacheManager();
ehCacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject());
return ehCacheManager;
}
@Bean
@DependsOn({ "lifecycleBeanPostProcessor" })
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
proxyCreator.setProxyTargetClass(true);
return proxyCreator;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean(name = "securityManager")
public SecurityManager securityManager() {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(jwtRealm());
// 关闭shiro自带的session
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
defaultWebSecurityManager.setSubjectDAO(subjectDAO);
// 自定义缓存管理器
defaultWebSecurityManager.setCacheManager(shiroCacheManager());
SecurityUtils.setSecurityManager(defaultWebSecurityManager);
return defaultWebSecurityManager;
}
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashIterations(2);// 散列的次数,比如散列两次,相当于
// md5(md5(""));
return hashedCredentialsMatcher;
}
@Bean
public JWTRealm jwtRealm() {
JWTRealm jwtRealm = new JWTRealm();
return jwtRealm;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager());
return advisor;
}
}