Springboot+Shiro+Mybatis+Thymeleaf-爱代码爱编程
首先是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";
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/Andy8921/article/details/106501127