shiro
apache shiro 是一个轻量级的身份验证与授权框架,与spring security 相比较,简单易用,灵活性高,springboot本身是提供了对security的支持,毕竟是自家的东西。springboot暂时没有集成shiro,这得自己配。
1 . 添加依赖
org.apache.shiro shiro-spring1.2.5 org.apache.shiro shiro-ehcache1.2.5
2 . 编写Shiro配置类
package com.xbz.web.system.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.base64;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
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.cookieRememberMeManager;
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.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import java.util.ArrayList;
import java.util.Collection;
import java.util.linkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfiguration {
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager());
shiroFilterFactoryBean.setLoginUrl("/login");//不设置默认找web工程根目录下的login.jsp页面
shiroFilterFactoryBean.setSuccessUrl("/index");//登录成功之后要跳转的连接
shiroFilterFactoryBean.setUnauthorizedUrl("/403");//未授权跳转页面
// Map filters = new linkedHashMap<>();
// LogoutFilter logoutFilter = new LogoutFilter();//限制同一帐号同时在线的个数。或单点登录等
// logoutFilter.setRedirectUrl("/login");
// filters.put("logout",null);
// shiroFilterFactoryBean.setFilters(filters);
Map filterChainDefinitionMap = new linkedHashMap<>();
//filterChainDefinitionManager必须是linkedHashMap因为它必须保证有序
filterChainDefinitionMap.put("/css
public Simplecookie rememberMecookie(){
//这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
Simplecookie simplecookie = new Simplecookie(cookie_NAME);
simplecookie.setMaxAge(604800);//记住我cookie生效时间7天 ,单位秒
return simplecookie;
}
public cookieRememberMeManager rememberMeManager(){
cookieRememberMeManager cookieRememberMeManager = new cookieRememberMeManager();
cookieRememberMeManager.setcookie(rememberMecookie());
cookieRememberMeManager.setCipherKey(base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
return cookieRememberMeManager;
}
@Bean
SessionDAO sessionDAO() {
return new MemorySessionDAO();
}
@Bean
public SessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
Collection listeners = new ArrayList<>();
listeners.add(new BDSessionListener());
sessionManager.setSessionListeners(listeners);
sessionManager.setSessionDAO(sessionDAO());
return sessionManager;
}
// ==================== cookie及Session管理 end ====================
//endregion
@Bean(name = "securityManager")
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
securityManager.setCacheManager(ehCacheManager());////用户授权/认证信息Cache, 采用EhCache 缓存
// 自定义session管理 使用redis
securityManager.setSessionManager(sessionManager());
//注入记住我管理器;
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public ShiroRealm shiroRealm(CredentialsMatcher matcher) {
ShiroRealm realm = new ShiroRealm();
realm.setCredentialsMatcher(matcher);//密码校验实现
return realm;
}
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public EhCacheManager ehCacheManager() {
EhCacheManager em = new EhCacheManager();
em.setCacheManagerConfigFile("classpath:config/ehcache.xml");//配置文件路径
return em;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean(name = "hashedCredentialsMatcher")
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("MD5");//指定加密方式方式,也可以在这里加入缓存,当用户超过五次登陆错误就锁定该用户禁止不断尝试登陆
credentialsMatcher.setHashIterations(2);
credentialsMatcher.setStoredCredentialsHexEncoded(true);
return credentialsMatcher;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager());
return advisor;
}
//thymeleaf模板引擎和shiro整合时使用
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
}
3 . 自定义Realm验证类
package com.yiyun.web.system.config;
import com.yiyun.dao.master.UserDao;
import com.yiyun.domain.UserDO;
import com.yiyun.web.common.utils.ShiroUtils;
import com.yiyun.web.system.service.MenuService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
public class ShiroRealm extends AuthorizingRealm {
// 一般这里都写的是servic
@Autowired
private UserDao userMapper;
@Autowired
private MenuService menuService;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
UserDo user = userMapper.findByName(token.getUsername());//查出是否有此用户
if(user != null){
// 若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验
List rlist = uRoleDao.findRoleByUid(user.getId());//获取用户角色
List plist = uPermissionDao.findPermissionByUid(user.getId());//获取用户权限
List roleStrlist=new ArrayList();////用户的角色集合
List perminsStrlist=new ArrayList();//用户的权限集合
for (URole role : rlist) {
roleStrlist.add(role.getName());
}
for (UPermission uPermission : plist) {
perminsStrlist.add(uPermission.getName());
}
user.setRoleStrlist(roleStrlist);
user.setPerminsStrlist(perminsStrlist);
Session session = SecurityUtils.getSubject().getSession();
session.setAttribute("user", user);//成功则放入session
// 若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验
return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
}
return null;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取当前登录输入的用户名,等价于(String) principalCollection.fromRealm(getName()).iterator().next();
// String loginName = (String) super.getAvailablePrincipal(principalCollection);
UserDo user = (UserDo) principalCollection.getPrimaryPrincipal();
// //到数据库查是否有此对象
// User user = null;// 实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
// user = userMapper.findByName(loginName);
if (user != null) {
//权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//用户的角色集合
info.addRoles(user.getRoleStrlist());
//用户的权限集合
info.addStringPermissions(user.getPerminsStrlist());
return info;
}
// 返回null的话,就会导致任何用户访问被拦截的请求时,都会自动跳转到unauthorizedUrl指定的地址
return null;
}
}
4 . 最后看一下ehcache的配置文件
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



