提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
—参与到一个新的项目使用的shiro框架作为安全框架,在网上参考文章得到了些启发记录一下shiro 的认证授权流程
提示:以下是本篇文章正文内容,下面案例可供参考
shiro 认证流程的实现
1.继承AuthorizingRealm 类重写doGetAuthenticationInfo()方法
代码如下(示例):
public class UserRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 1. 把AuthenticationToken转换为CustomizedToken
//2.CustomizedToken 继承自UsernamePasswordToken
// (可用于存放自定义的一些用户信息)
CustomizedToken customizedToken = (CustomizedToken) token;
// 3. 从CustomizedToken中获取用户信息
Long confId = customizedToken.getConferenceId();
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
//查询数据库做用户相关判断
.........
// 认证通过,则返回认证info给shiro进一步处理:如缓存等。
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(loginUser, password, realname);
//loginUser 为存贮的身份信息
return info;
2.重写doGetAuthorizationInfo()
代码如下(示例):
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//1.从 principals 中获取当前登录的用户信息
LoginUser user = (LoginUser) principals.getPrimaryPrincipal();
//2.获取用户的所有权限
List<String> permsList = new ArrayList<>();
permsList = shiroService.getAllPerms();
permsList = shiroService.getAllPermsByUserId(user.getId());
//3.用户权限封装为set列表
Set<String> permsSet = new HashSet<String>();
for (String perms : permsList) {
if (StringUtils.isBlank(perms)) {
continue;
permsSet.addAll(Arrays.asList(perms.trim().split(",")));
}
}
//4.权限存如缓存
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(permsSet);
return info;
}
3.配置shiro配置类
@Configuration
public class ShiroDetailConfig {
@Bean
public UserRealm getRealm() {
// 1、获取配置的Realm,之所以没使用注解配置,是因为此处需要考虑到加密处理
UserRealm realm = new UserRealm();
realm.setName("HYH_OA_USER_REALM_NAME");
realm.setCachingEnabled(true);
realm.setAuthenticationCacheName("authenticationCache");
realm.setAuthenticationCachingEnabled(true);
realm.setAuthorizationCacheName("authorizationCache");
realm.setAuthorizationCachingEnabled(true);
realm.setCacheManager(getCacheManager());
return realm;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
//代理 授权核心配置
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
daap.setProxyTargetClass(true);
return daap;
}
//配置通知//授权的核心
@Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(
DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
aasa.setSecurityManager(securityManager);
return aasa;
}
@Bean
public RedisCacheManager getCacheManager() {
//缓存配置
RedisCacheManager cacheManager = new RedisCacheManager();
cacheManager.setRedisManager(getRedisManger());
return cacheManager;
}
@Bean
public RedisManager getRedisManger() {
return new RedisManager();
}
@Bean("sessionManager")
public DefaultWebSessionManager getSessionManager(SessionDAO sessionDAO) { // 6
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setGlobalSessionTimeout(3600000); //设置session过期时间为1小时(单位:毫秒),默认为30分钟
sessionManager.setSessionValidationSchedulerEnabled(true);
sessionManager.setSessionIdUrlRewritingEnabled(false);
sessionManager.setSessionDAO(sessionDAO);
return sessionManager;
}
@Bean("securityManager")
//设置管理器
public DefaultWebSecurityManager getSecurityManager(Realm userRealm, RedisCacheManager cacheManager,
SessionManager sessionManager, RememberMeManager rememberMeManager) {// 7
DefaultWebSecurityManager securityManager = new StatelessSecurityManager();
securityManager.setRealm(userRealm);
securityManager.setCacheManager(getCacheManager());
securityManager.setSessionManager(sessionManager);
securityManager.setRememberMeManager(rememberMeManager);
return securityManager;
}
@Bean("shiroFilter")
//shrio过滤器
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必须设置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/loginException"); // 设置登录页路径
shiroFilterFactoryBean.setSuccessUrl("/"); // 设置跳转成功页
shiroFilterFactoryBean.setUnauthorizedUrl("/authorizedException"); // 授权错误页
Map<String, Filter> filters = new HashMap<String, Filter>();
filters.put("statelessAuth", this.getOAuth2Filter());
shiroFilterFactoryBean.setFilters(filters);
Map<String, String> filterChainDefinitionMap = new HashMap<String, String>();
//添加拦截资源
//anon 不需要验证的资源
//authc 需要认证才可访问
//role 资源需要得到角色才可
//perms 资源访问需要得到资源
filterChainDefinitionMap.put("/login", "anon");
// 请求拦截路径
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
}
执行登录
@PostMapping("/login")
public Response loginServerSystem(@NotEmpty String userName, @NotEmpty String password) throws IOException {
Subject subject = ShiroUtil.getSubject();
// sha256加密
password = new Sha256Hash(password).toHex();
// UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
CustomizedToken token = new CustomizedToken(userName, password
, CommonConstant.LOGIN_USER_SYSTEM, DictoryConstant.USER_BELONG_TO_HOME);
subject.login(token);
接口权限
接口上加注解:@RequiresPermissions(“user:del”)
总结
写得潦草,欢迎各位大佬指导
参考文章:https://hardy.blog.youkuaiyun.com/article/details/110501155?spm=1001.2014.3001.5506