package cn
.com
.suntree
.treetask
.config
;
import cn
.com
.suntree
.common
.ding
.model
.DingUserDo
;
import cn
.com
.suntree
.common
.entity
.SysUser
;
import cn
.com
.suntree
.common
.entity
.returnvo
.PowerVo
;
import cn
.com
.suntree
.common
.entity
.returnvo
.RoleVo
;
import cn
.com
.suntree
.common
.mapper
.DingUserMapper
;
import cn
.com
.suntree
.common
.mapper
.RoleMapper
;
import cn
.com
.suntree
.common
.service
.CmpUserService
;
import cn
.com
.suntree
.common
.service
.MenuService
;
import cn
.com
.suntree
.common
.utils
.YAMLUtils
;
import cn
.com
.suntree
.utils
.myself
.CommonUtil
;
import lombok
.extern
.log4j
.Log4j2
;
import org
.apache
.shiro
.authc
.*
;
import org
.apache
.shiro
.authc
.credential
.CredentialsMatcher
;
import org
.apache
.shiro
.authc
.credential
.HashedCredentialsMatcher
;
import org
.apache
.shiro
.authz
.AuthorizationInfo
;
import org
.apache
.shiro
.authz
.SimpleAuthorizationInfo
;
import org
.apache
.shiro
.mgt
.SecurityManager
;
import org
.apache
.shiro
.realm
.AuthorizingRealm
;
import org
.apache
.shiro
.session
.Session
;
import org
.apache
.shiro
.session
.UnknownSessionException
;
import org
.apache
.shiro
.session
.mgt
.ExecutorServiceSessionValidationScheduler
;
import org
.apache
.shiro
.session
.mgt
.eis
.EnterpriseCacheSessionDAO
;
import org
.apache
.shiro
.spring
.security
.interceptor
.AuthorizationAttributeSourceAdvisor
;
import org
.apache
.shiro
.spring
.web
.ShiroFilterFactoryBean
;
import org
.apache
.shiro
.subject
.PrincipalCollection
;
import org
.apache
.shiro
.web
.mgt
.DefaultWebSecurityManager
;
import org
.apache
.shiro
.web
.servlet
.SimpleCookie
;
import org
.apache
.shiro
.web
.session
.mgt
.DefaultWebSessionManager
;
import org
.crazycake
.shiro
.RedisCacheManager
;
import org
.crazycake
.shiro
.RedisManager
;
import org
.crazycake
.shiro
.RedisSessionDAO
;
import org
.crazycake
.shiro
.SerializeUtils
;
import org
.slf4j
.Logger
;
import org
.slf4j
.LoggerFactory
;
import org
.springframework
.aop
.framework
.autoproxy
.DefaultAdvisorAutoProxyCreator
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.beans
.factory
.annotation
.Qualifier
;
import org
.springframework
.context
.annotation
.Bean
;
import org
.springframework
.context
.annotation
.Configuration
;
import org
.springframework
.context
.annotation
.Lazy
;
import javax
.servlet
.Filter
;
import java
.io
.Serializable
;
import java
.util
.*
;
@Log4j2
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean
shiroFilter(SecurityManager securityManager
) {
ShiroFilterFactoryBean shiroFilterFactoryBean
= new ShiroFilterFactoryBean();
shiroFilterFactoryBean
.setSecurityManager(securityManager
);
Map
<String, Filter> filtersMap
= new LinkedHashMap<String, Filter>();
shiroFilterFactoryBean
.setFilters(filtersMap
);
HashMap
<String, String> filterMap
= new LinkedHashMap<>();
filterMap
.put("/api/enclosure/download", "anon");
filterMap
.put("/api/register/**", "anon")
filterMap
.put("/api/delay/**","anon");
filterMap
.put("/api/**", "authc");
shiroFilterFactoryBean
.setLoginUrl("/login");
shiroFilterFactoryBean
.setUnauthorizedUrl("/codelogin");
shiroFilterFactoryBean
.setUnauthorizedUrl("/ddlogin/**");
shiroFilterFactoryBean
.setUnauthorizedUrl("/error");
shiroFilterFactoryBean
.setFilterChainDefinitionMap(filterMap
);
return shiroFilterFactoryBean
;
}
@Bean
public SecurityManager
securityManager(@Qualifier("myShiroRealm") MyShiroRealm myShiroRealm
) {
DefaultWebSecurityManager securityManager
= new DefaultWebSecurityManager();
securityManager
.setCacheManager(cacheManager());
securityManager
.setSessionManager(sessionManager());
securityManager
.setRealm(myShiroRealm
);
return securityManager
;
}
@Bean
public MyShiroRealm
myShiroRealm() {
MyShiroRealm myShiroRealm
= new MyShiroRealm();
myShiroRealm
.setCredentialsMatcher(credentialsMatcher());
myShiroRealm
.setCacheManager(cacheManager());
return myShiroRealm
;
}
public RedisCacheManager
cacheManager() {
RedisCacheManager redisCacheManager
= new RedisCacheManager();
redisCacheManager
.setRedisManager(redisManager());
return redisCacheManager
;
}
public RedisManager
redisManager() {
RedisManager redisManager
= new RedisManager();
redisManager
.setHost(host
);
redisManager
.setPort(port
);
redisManager
.setExpire(expireTm
);
redisManager
.setTimeout(0);
redisManager
.setPassword(passwd
);
return redisManager
;
}
@Bean(name
= "sessionIdCookie")
public SimpleCookie
sessionIdCookie() {
SimpleCookie cookie
= new SimpleCookie();
cookie
.setName("WEBS");
cookie
.setHttpOnly(true);
cookie
.setMaxAge(-1);
return cookie
;
}
@Bean
public DefaultWebSessionManager
sessionManager() {
DefaultWebSessionManager sessionManager
= new DefaultWebSessionManager();
sessionManager
.setGlobalSessionTimeout(28800000L
);
sessionManager
.setSessionIdCookieEnabled(true);
sessionManager
.setSessionValidationScheduler(getExecutorServiceSessionValidationScheduler());
sessionManager
.setSessionIdCookie(sessionIdCookie());
sessionManager
.setSessionDAO(redisSessionDAO());
return sessionManager
;
}
@Bean(name
= "sessionValidationScheduler")
public ExecutorServiceSessionValidationScheduler
getExecutorServiceSessionValidationScheduler() {
ExecutorServiceSessionValidationScheduler scheduler
= new ExecutorServiceSessionValidationScheduler();
scheduler
.setInterval(900000);
return scheduler
;
}
public class MyRedisSessionDAO extends RedisSessionDAO {
private Logger logger
= LoggerFactory
.getLogger(MyRedisSessionDAO
.class);
private RedisManager redisManager
;
private String keyPrefix
= "cmp_shiro_redis_session:";
public MyRedisSessionDAO() {
}
public void update(Session session
) throws UnknownSessionException
{
this.saveSession(session
);
}
private void saveSession(Session session
) throws UnknownSessionException
{
if (session
!= null
&& session
.getId() != null
) {
byte[] key
= this.getByteKey(session
.getId());
byte[] value
= SerializeUtils
.serialize(session
);
session
.setTimeout((long) (this.redisManager
.getExpire() * 1000));
this.redisManager
.set(key
, value
, this.redisManager
.getExpire());
} else {
logger
.error("session or session id is null");
}
}
public void delete(Session session
) {
if (session
!= null
&& session
.getId() != null
) {
this.redisManager
.del(this.getByteKey(session
.getId()));
} else {
logger
.error("session or session id is null");
}
}
public Collection
<Session> getActiveSessions() {
Set
<Session> sessions
= new HashSet();
Set
<byte[]> keys
= this.redisManager
.keys(this.keyPrefix
+ "*");
if (keys
!= null
&& keys
.size() > 0) {
Iterator i$
= keys
.iterator();
while (i$
.hasNext()) {
byte[] key
= (byte[]) i$
.next();
Session s
= (Session
) SerializeUtils
.deserialize(this.redisManager
.get(key
));
sessions
.add(s
);
}
}
return sessions
;
}
protected Serializable
doCreate(Session session
) {
Serializable sessionId
= this.generateSessionId(session
);
this.assignSessionId(session
, sessionId
);
this.saveSession(session
);
return sessionId
;
}
protected Session
doReadSession(Serializable sessionId
) {
if (sessionId
== null
) {
logger
.error("session id is null");
return null
;
} else {
Session s
= (Session
) SerializeUtils
.deserialize(this.redisManager
.get(this.getByteKey(sessionId
)));
return s
;
}
}
private byte[] getByteKey(Serializable sessionId
) {
String preKey
= this.keyPrefix
+ sessionId
;
return preKey
.getBytes();
}
public RedisManager
getRedisManager() {
return this.redisManager
;
}
public void setRedisManager(RedisManager redisManager
) {
this.redisManager
= redisManager
;
this.redisManager
.init();
}
public String
getKeyPrefix() {
return this.keyPrefix
;
}
public void setKeyPrefix(String keyPrefix
) {
this.keyPrefix
= keyPrefix
;
}
}
@Bean
public MyRedisSessionDAO
redisSessionDAO() {
MyRedisSessionDAO redisSessionDAO
= new MyRedisSessionDAO();
redisSessionDAO
.setRedisManager(redisManager());
return redisSessionDAO
;
}
@Bean
public DefaultAdvisorAutoProxyCreator
defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP
= new DefaultAdvisorAutoProxyCreator();
defaultAAP
.setProxyTargetClass(true);
return defaultAAP
;
}
@Bean
public AuthorizationAttributeSourceAdvisor
authorizationAttributeSourceAdvisor(SecurityManager securityManager
) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor
= new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor
.setSecurityManager(securityManager
);
return authorizationAttributeSourceAdvisor
;
}
@Bean
public CredentialsMatcher
credentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher
= new HashedCredentialsMatcher();
hashedCredentialsMatcher
.setHashAlgorithmName("md5");
return hashedCredentialsMatcher
;
}
public class MyShiroRealm extends AuthorizingRealm {
@Autowired
@Lazy
private CmpUserService userService
;
@Autowired
@Lazy
private RoleMapper roleMapper
;
@Override
protected AuthorizationInfo
doGetAuthorizationInfo(PrincipalCollection principalCollection
) {
SysUser user
= (SysUser
) principalCollection
.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo
= new SimpleAuthorizationInfo();
authorizationInfo
.setRoles(new HashSet<>(userService
.listRoleNameByUser(user
)));
authorizationInfo
.setStringPermissions(new HashSet<>(userService
.listPowerNameByUser(user
)));
return authorizationInfo
;
}
@Override
protected AuthenticationInfo
doGetAuthenticationInfo(AuthenticationToken authenticationToken
) throws AuthenticationException
{
String key
= (String
) authenticationToken
.getPrincipal();
boolean isPhomeToken
= authenticationToken
instanceof AuthenticationTokenMobilePhone;
SysUser u
= new SysUser();
u
.setAccNum(key
);
SysUser user
= isPhomeToken
? ((AuthenticationTokenMobilePhone
) authenticationToken
).getUser() : userService
.getUserByAcc(u
);
if (user
== null
) {
throw new UnknownAccountException();
} else if ("0".equals(user
.getIsLock())) {
throw new LockedAccountException();
}
String credentials
= isPhomeToken
?
"d036a5788f9ffade1893be5eb5cee798" : user
.getPasswd();
if(!CommonUtil
.checkStr(credentials
) || user
.getIsActive()==0){
throw new AuthenticationException("该账号未激活,请先注册激活");
}
SimpleAuthenticationInfo simpleAuthenticationInfo
=
new SimpleAuthenticationInfo(user
, credentials
, this.getName());
return simpleAuthenticationInfo
;
}
@Override
public boolean supports(AuthenticationToken token
) {
return true;
}
}
}