- 什么是Shrio?—一个NB的安全框架!号称世界上最火的企业级别安全框架(我编的)!
- 可以干什么?—可以完成,认证,授权,加密,会话管理,Web集成,缓存等.说人话:就是过滤器封装版本及扩展版!有了它之后,什么繁琐的登录验证啊,拦截器啊都可以托管了,关键shrio运用AOP思想,横切代码,让你的源码受不到一点伤害!
What can shrio do ?
- 三个核心组件:Subject, SecurityManager 和 Realms.
*Subject*
: 即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。
Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
SecurityManager
:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
Realm(真男人)
: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。
Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果系统默认的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。
How to use ?
0、导入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.1</version>
</dependency>
- 搭配springboot食用更佳!
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
或者
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
</dependency>
不过前者用的多
1、编写Realm类继承AuthorizingRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
//这里写你项目用到的service
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权");
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
//info.addStringPermission("user:add");
//拿到当前用户登陆对象
Subject subject= SecurityUtils.getSubject();
User currentUser= (User) subject.getPrincipal();//拿到User对象
info.addStringPermission(currentUser.getPerms());//设置当前用户对象
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了认证");
//用户名,密码,数据库中获取
UsernamePasswordToken userToken=(UsernamePasswordToken) authenticationToken;
User user=userService.queryUserByName(userToken.getUsername());//获取用户名
String name=user.getName();
String password=user.getPwd();
if(user==null){//说明查无此人
return null;
}
//密码认证,shiro做
return new SimpleAuthenticationInfo(user,password,"");//放入User对象
}
2、编写配置类ShrioConfig
@Configuration
public class ShiroConfig {
//shiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加shiro的内置过滤器
/*
anon: 无需认证就可访问
authc:必须认证才能访问
user:必须拥有记住我功能才能访问
perms: 拥有对某个资源的权限才能访问
role:拥有某个角色权限才能访问
*/
Map<String, String> filterMap = new LinkedHashMap<>();
//
// //授权
// filterMap.put("/user/add","perms[user:add]");
// filterMap.put("/user/update","perms[user:update]");
//授权
filterMap.put("/user/**", "roles[user]");
filterMap.put("/admin/**", "roles[admin]");
//过滤请求
filterMap.put("/error/**", "anon");
filterMap.put("/", "anon");
filterMap.put("/index.html", "anon");
filterMap.put("/toregister.html", "anon");
filterMap.put("/login/**", "anon");
filterMap.put("/asserts/**", "anon");
filterMap.put("/bootstrap/**", "anon");
filterMap.put("/images/**", "anon");
filterMap.put("/lyear/**", "anon");
filterMap.put("/js/**", "anon");
//对所有请求认证
//主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截
filterMap.put("/**", "authc");
// filterMap.put("/user/*", "authc");
// filterMap.put("/admin/*", "authc");
//设置登出
//filterMap.put("/logout", "logout");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录请求(认证界面)
bean.setLoginUrl("/");
// //设置未授权页面
// bean.setUnauthorizedUrl("/noauth");
return bean;
}
// DafaultWebSecurityManager
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联UserRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//创建realm对象 ,需要自定义
@Bean(name = "userRealm")
public UserRealm userRealm() {
return new UserRealm();
}
//整合thymeleaf
@Bean
public ShiroDialect getShiroDialect() {
return new ShiroDialect();
}
}
- 特别注意授权顺序问题,
就这?
就这
项目遇到的是后直接拷过去改改就行