首先是pom.xml注入依賴包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
UserShiroRealm
public class UserShiroRealm extends AuthorizingRealm {
@Autowired
SysUserService sysUserService;
@Autowired
SysRoleService sysRoleService;
@Autowired
SysMenuService sysMenuService;
/**
* 身份認證
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
log.debug("UserShiroRealm.doGetAuthenticationInfo{}", Constants.SHOW_DEBUG_TAG);
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
log.info("驗證當前Subject時獲取到token爲:{}",token.toString());
//查出是否有此用戶
//獲取用戶的輸入的賬號
String username = token.getUsername();
//實際項目中,這裏可以根據實際情況做緩存,如果不做,Shiro自己也是有時間間隔機制,2分鐘內不會重複執行該方法
SysUser hasSysUser = sysUserService.getUserByLoginAllInfo(username,null);
// log.info("hasSysUser:{}",hasSysUser);
if (hasSysUser == null) {
////沒有返回登錄用戶名對應的SimpleAuthenticationInfo對象時,就會在LoginController中拋出UnknownAccountException異常
return null;
}else {
// 可放在doGetAuthorizationInfo中執行
// 若存在,將此用戶存放到登錄認證info中,無需自己做密碼對比,Shiro會爲我們進行密碼對比校驗
// List<URole> rlist = uRoleDao.findRoleByUid(hasUser.getId());//獲取用戶角色
// List<UPermission> plist = uPermissionDao.findPermissionByUid(hasUser.getId());//獲取用戶權限
// List<String> roleStrlist=new ArrayList<String>();////用戶的角色集合
// List<String> perminsStrlist=new ArrayList<String>();//用戶的權限集合
// for (URole role : rlist) {
// roleStrlist.add(role.getName());
// }
// for (UPermission uPermission : plist) {
// perminsStrlist.add(uPermission.getName());
// }
// hasUser.setRoleStrlist(roleStrlist);
// hasUser.setPerminsStrlist(perminsStrlist);
}
ByteSource credentialsSalt = ByteSource.Util.bytes(hasSysUser.getLoginName()+hasSysUser.getSalt());
String loginPwd = hasSysUser.getLoginPwd();
hasSysUser.setLoginPwd("");
// 若存在,將此用戶存放到登錄認證info中,無需自己做密碼對比,Shiro會爲我們進行密碼對比校驗
//此處沒有加鹽
//hasSysUser 認證成功的返回信息
SimpleAuthenticationInfo simpleAuthenticationInfo =
new SimpleAuthenticationInfo(hasSysUser, loginPwd,credentialsSalt, getName());
return simpleAuthenticationInfo;
}
/**
* 權限認證
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
log.debug("UserShiroRealm.doGetAuthorizationInfo{}", "執行Shiro權限認證"+Constants.SHOW_DEBUG_TAG);
SysUser sysUser = (SysUser) principalCollection.getPrimaryPrincipal();
//權限信息對象info,用來存放查出的用戶的所有的角色(role)及權限(permission)
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 管理員擁有所有權限
if (sysUser.getUserType().equals(0)) {
// if (false) {
authorizationInfo.addStringPermission("*:*:*");
}else {
if (sysUser != null) {
//獲取用戶角色
List<SysRole> sysUserRoleList = sysRoleService.getSysRoleInfoUserListForShiro(sysUser.getId());
for (SysRole r : sysUserRoleList) {
authorizationInfo.addRole(r.getRoleKey());
//獲取用戶權限
List<SysMenu> sysUserRoleMenuList = sysMenuService.getSysMenuInfoRoleListForShiro(r.getId());
for (SysMenu m : sysUserRoleMenuList) {
authorizationInfo.addStringPermission(m.getPerms());
}
}
}
}
// 返回null的話,就會導致任何用戶訪問被攔截的請求時,都會自動跳轉到unauthorizedUrl指定的地址
return authorizationInfo;
}
/**
* 清理當前緩存權限
*/
public void clearCachedAuthorizationInfo() {
log.debug("UserShiroRealm.clearCachedAuthorizationInfo{}", "執行Shiro權限認證"+Constants.SHOW_DEBUG_TAG);
this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
}
/**
* 重寫方法,清除當前用戶的的 授權緩存
* @param principals
*/
@Override
public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
super.clearCachedAuthorizationInfo(principals);
}
/**
* 重寫方法,清除當前用戶的 認證緩存
* @param principals
*/
@Override
public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
super.clearCachedAuthenticationInfo(principals);
}
/**
* 自定義方法:清除所有 授權緩存
*/
public void clearAllCachedAuthorizationInfo() {
getAuthorizationCache().clear();
}
/**
* 自定義方法:清除所有 認證緩存
*/
public void clearAllCachedAuthenticationInfo() {
getAuthenticationCache().clear();
}
/**
* 自定義方法:清除所有的 認證緩存 和 授權緩存
*/
public void clearAllCache() {
clearAllCachedAuthenticationInfo();
clearAllCachedAuthorizationInfo();
}
}
ShiroConfiguration
@Configuration
public class ShiroConfiguration {
/**
* ShiroFilterFactoryBean 處理攔截資源文件問題。
* 注意:單獨一個ShiroFilterFactoryBean配置是或報錯的,以爲在
* 初始化ShiroFilterFactoryBean的時候需要注入:SecurityManager
*
* Filter Chain定義說明 1、一個URL可以配置多個Filter,使用逗號分隔 2、當設置多個過濾器時,全部驗證通過,才視爲通過
* 3、部分過濾器可指定參數,如perms,roles
*
*/
@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
log.debug("ShiroConfiguration.shiroFilterFactoryBean{}", Constants.SHOW_DEBUG_TAG);
// 過濾鏈定義,從上向下順序執行,一般將 /**放在最爲下邊
Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>();
// authc:所有url都必須認證通過纔可以訪問; anon:所有url都都可以匿名訪問
filterChainDefinitionManager.put("/error", "anon");
filterChainDefinitionManager.put("/static/**", "anon");
//排除訪問swagger
filterChainDefinitionManager.put( "/swagger-resources/**", "anon");
filterChainDefinitionManager.put( "/v2/**", "anon");
filterChainDefinitionManager.put( "/swagger-ui.html/**", "anon");
filterChainDefinitionManager.put("/webjars/**", "anon");
filterChainDefinitionManager.put("/index.html", "anon");
filterChainDefinitionManager.put("/login.html", "anon");
filterChainDefinitionManager.put("/sys/login/getCaptcha", "anon");
filterChainDefinitionManager.put("/sys/login", "anon");
// 配置退出過濾器,其中的具體的退出代碼Shiro已經替我們實現了
// filterChainDefinitionManager.put("/sys/loginOut", "authc");
// filterChainDefinitionManager.put("/sys/**", "authc");
// filterChainDefinitionManager.put("/**", "authc");//其他資源全部攔截,必須通過身份認證成功可通過
filterChainDefinitionManager.put("/**", "user");//其他資源全部攔截.身份認證成功或通過記住我均可通過
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);
// 如果不設置默認會自動尋找Web工程根目錄下的"/login.jsp"頁面
shiroFilterFactoryBean.setLoginUrl("/login.html");
// 登錄成功後要跳轉的鏈接
// shiroFilterFactoryBean.setSuccessUrl("/home.html");
// 未授權界面
// shiroFilterFactoryBean.setUnauthorizedUrl("/403");
return shiroFilterFactoryBean;
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//設置realm
securityManager.setRealm(userShiroRealm());
//用戶授權/認證信息Cache, 採用EhCache 緩存 注入緩存管理器;
securityManager.setCacheManager(ehCacheManager());//這個如果執行多次,也是同樣的一個對象;
securityManager.setRememberMeManager(rememberMeManager());
//配置自定義session管理,使用ehcache 或redis
securityManager.setSessionManager(sessionManager());
return securityManager;
}
//身份認證與權限認證
@Bean(name = "userShiroRealm")
@DependsOn("lifecycleBeanPostProcessor")
public UserShiroRealm userShiroRealm() {
UserShiroRealm userShiroRealm = new UserShiroRealm();
//緩存開關 setCachingEnabled 管理 setAuthenticationCachingEnabled,setAuthorizationCachingEnabled
userShiroRealm.setCachingEnabled(false);
//啓用身份驗證緩存,即緩存AuthenticationInfo信息,默認false
// userShiroRealm.setAuthenticationCachingEnabled(false);
//緩存AuthenticationInfo信息的緩存名稱 在ehcache-shiro.xml中有對應緩存的配置
userShiroRealm.setAuthenticationCacheName("authenticationCache");
//啓用授權緩存,即緩存AuthorizationInfo信息,默認false
// userShiroRealm.setAuthorizationCachingEnabled(false);
//緩存AuthorizationInfo信息的緩存名稱 在ehcache-shiro.xml中有對應緩存的配置
userShiroRealm.setAuthorizationCacheName("authorizationCache");
userShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return userShiroRealm;
}
/**
* 憑證匹配器
* (由於我們的密碼校驗交給Shiro的SimpleAuthenticationInfo進行處理了
* 所以我們需要修改下doGetAuthenticationInfo中的代碼;
* )
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:這裏使用MD5算法;
hashedCredentialsMatcher.setHashIterations(2);//散列的次數,比如散列兩次,相當於 md5(md5(""));
return hashedCredentialsMatcher;
}
@Bean(name = "ehCacheManager")
@DependsOn("lifecycleBeanPostProcessor")
public EhCacheManager ehCacheManager(){
EhCacheManager ehCacheManager = new EhCacheManager();
ehCacheManager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
return ehCacheManager;
}
/**
* cookie對象;
* @return
*/
@Bean
public SimpleCookie rememberMeCookie(){
log.debug("ShiroConfiguration.rememberMeCookie()");
//這個參數是cookie的名稱,對應前端的checkbox的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//如果httyOnly設置爲true,則客戶端不會暴露給客戶端腳本代碼,使用HttpOnly cookie有助於減少某些類型的跨站點腳本攻擊;
// simpleCookie.setHttpOnly(true);
//<!-- 記住我cookie生效時間30天 ,單位秒;-->
simpleCookie.setMaxAge(259200);
//simpleCookie.setMaxAge(20);
return simpleCookie;
}
/**
* cookie管理對象;
* @return
*/
@Bean
public CookieRememberMeManager rememberMeManager(){
log.debug("ShiroConfiguration.rememberMeManager()");
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
//rememberme cookie加密的密鑰 建議每個項目都不一樣 默認AES算法 密鑰長度(128 256 512 位),通過以下代碼可以獲取
//KeyGenerator keygen = KeyGenerator.getInstance("AES");
//SecretKey deskey = keygen.generateKey();
//System.out.println(Base64.encodeToString(deskey.getEncoded()));
byte[] cipherKey = Base64.decode("wGiHplamyXlVB11UXWol8g==");
cookieRememberMeManager.setCipherKey(cipherKey);
cookieRememberMeManager.setCookie(rememberMeCookie());
return cookieRememberMeManager;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
/**
* 開啓shiro aop註解支持.
* 使用代理方式;所以需要開啓代碼支持;
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
/**
* 添加ShiroDialect 爲了在thymeleaf裏使用shiro的標籤的bean
* @return
*/
@Bean(name = "shiroDialect")
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
///附加功能///////////////////////////////
/**
* 配置session監聽
* @return
*/
@Bean("sessionListener")
public ShiroSessionListener sessionListener(){
ShiroSessionListener sessionListener = new ShiroSessionListener();
return sessionListener;
}
/**
* 配置會話ID生成器
* @return
*/
@Bean
public SessionIdGenerator sessionIdGenerator() {
return new JavaUuidSessionIdGenerator();
}
/**
* SessionDAO的作用是爲Session提供CRUD並進行持久化的一個shiro組件
* MemorySessionDAO 直接在內存中進行會話維護
* EnterpriseCacheSessionDAO 提供了緩存功能的會話維護,默認情況下使用MapCache實現,內部使用ConcurrentHashMap保存緩存的會話。
* @return
*/
@Bean
public SessionDAO sessionDAO() {
EnterpriseCacheSessionDAO enterpriseCacheSessionDAO = new EnterpriseCacheSessionDAO();
//使用ehCacheManager
enterpriseCacheSessionDAO.setCacheManager(ehCacheManager());
//設置session緩存的名字 默認爲 shiro-activeSessionCache
enterpriseCacheSessionDAO.setActiveSessionsCacheName("shiro-activeSessionCache");
//sessionId生成器
enterpriseCacheSessionDAO.setSessionIdGenerator(sessionIdGenerator());
return enterpriseCacheSessionDAO;
}
/**
* 配置保存sessionId的cookie
* 注意:這裏的cookie 不是上面的記住我 cookie 記住我需要一個cookie session管理 也需要自己的cookie
* @return
*/
@Bean("sessionIdCookie")
public SimpleCookie sessionIdCookie(){
//這個參數是cookie的名稱
SimpleCookie simpleCookie = new SimpleCookie("tank-sys");
//setcookie的httponly屬性如果設爲true的話,會增加對xss防護的安全係數。它有以下特點:
//setcookie()的第七個參數
//設爲true後,只能通過http訪問,javascript無法訪問
//防止xss讀取cookie
simpleCookie.setHttpOnly(true);
simpleCookie.setPath("/");
//maxAge=-1表示瀏覽器關閉時失效此Cookie
simpleCookie.setMaxAge(-1);
return simpleCookie;
}
/**
* 配置會話管理器,設定會話超時及保存
* @return
*/
@Bean("sessionManager")
public SessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
Collection<SessionListener> listeners = new ArrayList<SessionListener>();
//配置監聽
listeners.add(sessionListener());
sessionManager.setSessionListeners(listeners);
sessionManager.setSessionIdCookie(sessionIdCookie());
sessionManager.setSessionDAO(sessionDAO());
sessionManager.setCacheManager(ehCacheManager());
//全局會話超時時間(單位毫秒),默認30分鐘 暫時設置爲10秒鐘 用來測試
sessionManager.setGlobalSessionTimeout(1800000);
// sessionManager.setGlobalSessionTimeout(10000);
//是否開啓刪除無效的session對象 默認爲true
sessionManager.setDeleteInvalidSessions(true);
//是否開啓定時調度器進行檢測過期session 默認爲true
// sessionManager.setSessionValidationSchedulerEnabled(true);
//設置session失效的掃描時間, 清理用戶直接關閉瀏覽器造成的孤立會話 默認爲 1個小時
//設置該屬性 就不需要設置 ExecutorServiceSessionValidationScheduler 底層也是默認自動調用ExecutorServiceSessionValidationScheduler
//暫時設置爲 5秒 用來測試
sessionManager.setSessionValidationInterval(3600000);
// sessionManager.setSessionValidationInterval(5000);
//取消url 後面的 JSESSIONID
sessionManager.setSessionIdUrlRewritingEnabled(false);
return sessionManager;
}
}
ShiroSessionListener
public class ShiroSessionListener implements SessionListener {
/**
* 統計在線人數
* juc包下線程安全自增
*/
private final AtomicInteger sessionCount = new AtomicInteger(0);
/**
* 會話創建時觸發
* @param session
*/
@Override
public void onStart(Session session) {
//會話創建,在線人數加一
sessionCount.incrementAndGet();
}
/**
* 退出會話時觸發
* @param session
*/
@Override
public void onStop(Session session) {
//會話退出,在線人數減一
sessionCount.decrementAndGet();
}
/**
* 會話過期時觸發
* @param session
*/
@Override
public void onExpiration(Session session) {
//會話過期,在線人數減一
sessionCount.decrementAndGet();
}
/**
* 獲取在線人數使用
* @return
*/
public AtomicInteger getSessionCount() {
return sessionCount;
}
}
ShiroUtils
public class ShiroUtils {
public static Subject getSubject() {
return SecurityUtils.getSubject();
}
public static Session getSession() {
return SecurityUtils.getSubject().getSession();
}
public static void logout() {
getSubject().logout();
}
public static SysUser getSysUser() {
SysUser user = (SysUser) getSubject().getPrincipal();
/*if (obj != null) {
user = new SysUser();
BeanUtils.copyProperties(user, obj);
}*/
return user;
}
public static void setSysUser(SysUser user) {
Subject subject = getSubject();
PrincipalCollection principalCollection = subject.getPrincipals();
String realmName = principalCollection.getRealmNames().iterator().next();
PrincipalCollection newPrincipalCollection = new SimplePrincipalCollection(user, realmName);
// 重新加載Principal
subject.runAs(newPrincipalCollection);
}
public static void clearCachedAuthorizationInfo() {
RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
UserShiroRealm realm = (UserShiroRealm) rsm.getRealms().iterator().next();
realm.clearCachedAuthorizationInfo();
}
public static Long getUserId() {
Long userId =null;
Subject subject = getSubject();
if(subject.isAuthenticated()||subject.isRemembered())
userId=getSysUser().getId().longValue();
return userId;
}
public static String getLoginName() {
return getSysUser().getLoginName();
}
public static String getIp() {
return getSubject().getSession().getHost();
}
public static String getSessionId() {
return String.valueOf(getSubject().getSession().getId());
}
/**
* 生成隨機鹽
*/
public static String randomSalt() {
// 一個Byte佔兩個字節,此處生成的3字節,字符串長度爲6
SecureRandomNumberGenerator secureRandom = new SecureRandomNumberGenerator();
String hex = secureRandom.nextBytes(3).toHex();
return hex;
}
public static String getPassword(String name , Object password , String userSalt){
String hashAlgorithmName = "MD5";
Object salt = ByteSource.Util.bytes(name+userSalt);
int hashIterations = 2;
Object result = new SimpleHash(hashAlgorithmName, password, salt, hashIterations);
return result.toString();
}
ehcache-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="es">
<!--
緩存對象存放路徑
java.io.tmpdir:默認的臨時文件存放路徑。
user.home:用戶的主目錄。
user.dir:用戶的當前工作目錄,即當前程序所對應的工作路徑。
其它通過命令行指定的系統屬性,如“java –DdiskStore.path=D:\\abc ……”。
-->
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
<!-- 授權緩存 -->
<cache name="authorizationCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache>
<!-- 認證緩存 -->
<cache name="authenticationCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache>
<!-- session緩存 -->
<cache name="shiro-activeSessionCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache>
</ehcache>
SysLoginController
@RequestMapping("/login")
public String login(String loginName, String loginPwd, String captchaCode, boolean rememberMe , HttpServletRequest req, Model model)
{
try {
if(StringUtil.isObjectEmpty(loginName)||StringUtil.isObjectEmpty(loginPwd)){
model.addAttribute("message", RespCode.RespEnum.SYSUSER_LOGIN_20004.getDescribe());
return "login";
}
//從session中獲取隨機數
String inputStr = captchaCode;
String random = (String) req.getSession().getAttribute(RandomValidateCodeUtil.RANDOMCODEKEY);
// if(!captchaCode.equals(random)){//登錄麻煩暫去除
if(false){
model.addAttribute("message", RespCode.RespEnum.SYSUSER_LOGIN_20005.getDescribe());
return "login";
}
// 把用戶名和密碼封裝爲 UsernamePasswordToken 對象 rememberme token.setRememberMe(true);
UsernamePasswordToken token = new UsernamePasswordToken(loginName, loginPwd, rememberMe);
Subject currentUser = ShiroUtils.getSubject();
log.info("對用戶:{},進行登錄驗證..驗證開始",loginName);
currentUser.login(token);
//驗證是否登錄成功
if (currentUser.isAuthenticated()) {
log.info("用戶:[{}]登錄認證通過(這裏可以進行一些認證通過後的一些系統參數初始化操作)",loginName);
// req.getSession().setAttribute(PermissionsConstants.SYSUSER_CONSTANTS.SYS_USER_SESSION,ShiroUtils.getSysUser());
return "redirect:/sys/home";
} else {
token.clear();
log.info("用戶:[{}]登錄認證失敗,重新登陸",loginName);
return "login";
}
} catch ( UnknownAccountException uae ) {
log.info("對用戶:[{}]進行登錄驗證..驗證失敗-username wasn't in the system",loginName);
} catch ( IncorrectCredentialsException ice ) {
log.info("對用戶:[{}]進行登錄驗證..驗證失敗-password didn't match",loginName);
} catch ( LockedAccountException lae ) {
log.info("對用戶:[{}]進行登錄驗證..驗證失敗-account is locked in the system",loginName);
} catch ( AuthenticationException ae ) {
log.info("對用戶:[{}]進行登錄驗證..驗證失敗-password in the system",loginName);
}catch (Exception e){
log.info("對用戶:[{}]進行登錄驗證..驗證失敗-system",loginName);
e.printStackTrace();
}
model.addAttribute("message", RespCode.RespEnum.SYSUSER_LOGIN_20006.getDescribe());
return "login";
}
@PostMapping("/loginOut")
@ResponseBody
public RespData loginOut(HttpServletRequest req)
{
RespData respData = new RespData();
try
{
ShiroUtils.logout();
if(StringUtil.isObjectNotEmpty(ShiroUtils.getSysUser()))
respData.setRespInfo(false,RespCode.RespEnum.FAIL.getCode(), RespCode.RespEnum.FAIL.getDescribe());
respData.setRespInfo(true,RespCode.RespEnum.SUCCESS.getCode(), RespCode.RespEnum.SUCCESS.getDescribe());
}
catch (Exception e)
{
respData.setRespInfo(false,RespCode.RespEnum.FAIL.getCode(), RespCode.RespEnum.FAIL.getDescribe());
e.printStackTrace();
}
return respData;
}
權限控制
/**
* 用戶列表
* @param model
* @return
*/
@RequiresPermissions("1026902")
@GetMapping("/index")
public String index(Model model)
{
model.addAttribute("sysStatus_List",PermissionsConstants.SYSSTATUS_MAP());
return "sys/user/user-index";
}