shiro入门学习
shiro入门学习
shiro
shiro是一个轻量级的安全权限框架,可以完成认证、授权、加密、会话管理、与web集成、缓存等
shiro架构
- Subject:应用代码直接交互的对象就是
Subject
,也就是说Shiro的对外API核心就是Subject
,Subject代表了当前用户,这个用户不一定是一个具体的人,可以代表与当前应用交互的任何东西;与Subject
的所有交互都会委托给SecurityManager
- SecurityManager:安全管理器;即所有与安全相关的操作都会与
SecurityManager
交互,并且管理者所有Subject
;是shiro
的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVC
里面DispatcherServlet
的角色 - Realm:Shiro从Realm获取安全数据(如用户、角色、权限)
shiro hello world
Subject currentUser = SecurityUtils.getSubject();
Session session = currentUser.getSession();
currentUser.isAuthenticated()
currentUser.hasRole("xxx")
currentUser.getPrincipal()currentUser.isPermitted("xxx:xxx")
SpringBoot 集成Shiro
1、导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 整合shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.7.1</version>
</dependency>
</dependencies>
2、创建Shiro配置文件
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
return shiroFilterFactoryBean;
}
//DefaultWebSecurityManager
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(UserRealm userRealm){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//关联UserRealm
defaultWebSecurityManager.setRealm(userRealm);
return defaultWebSecurityManager;
}
//创建 realm对象
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
3、添加shiro过滤器
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加shiro过滤器
/** * anon:无需认证 * authc:必须认证才能访问 * user:必须拥有记住我,才可以访问 * perms:拥有对某个资源的权限才能访问 * role:拥有某个角色权限才能访问 */
Map<String, String> filterChainMap = new LinkedHashMap<>();
filterChainMap.put("/user/add","authc");
filterChainMap.put("/user/update","authc");
bean.setFilterChainDefinitionMap(filterChainMap);
//添加登录页面
bean.setLoginUrl("/toLogin");
return bean;
}
- 如果用户未登录访问需要认证的请求,会跳转到登录页面
4、用户认证
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//测试用户
String username = "root";
String password = "root";
UsernamePasswordToken user = (UsernamePasswordToken) token;
if (!(user.getUsername().equals(username))){
return null;//抛出异常 UnKnownAccountException
}
System.out.println("执行了认证方法");
//密码认证,shiro做
return new SimpleAuthenticationInfo("",password,"");
}
5、用户授权
//添加shiro过滤器
/** * anno:无需认证 * authc:必须认证才能访问 * user:必须拥有记住我,才可以访问 * perms:拥有对某个资源的权限才能访问 * role:拥有某个角色权限才能访问 */
Map<String, String> filterChainMap = new LinkedHashMap<>();
filterChainMap.put("/user/add","perms[user:add]");
filterChainMap.put("/user/update","authc");
bean.setFilterChainDefinitionMap(filterChainMap);
-
通过过滤器链或者注解的方式,添加路径和权限的关系,
-
在Realm类中进行授权操作
//自定义Realm public class UserRealm extends AuthorizingRealm { //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("执行了授权方法"); return null; }
-
未通过授权的用户会进入指定的url页面
bean.setUnauthorizedUrl("/unAuthorize");
-
用户可以获取当前登录的用户信息
SecurityUtils.getSubject().getPrincipal()
6、shiro和Thymeleaf整合
-
导入依赖
<!-- shiro整合thymeleaf--> <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency>
-
编写配置
//整合thymeleaf--ShiroDialect //在配置文件中添加 @Bean public ShiroDialect shiroDialect(){ return new ShiroDialect(); }
-
前端测试
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>首页</h1> <h3 th:text="${msg}"></h3> <h3 th:text="${user}"></h3> <!--根据当前登录的用户的权限,判断是否显示标签--> <a shiro:hasPermission="user:add" th:href="@{/user/add}">add</a> <a shiro:hasPermission="user:update" th:href="@{/user/update}">update</a> </body> </html>
guest标签 <shiro:guest> </shiro:guest> 用户没有身份验证时显示相应信息,即游客访问信息。 user标签 <shiro:user> </shiro:user> 用户已经身份验证/记住我登录后显示相应的信息。 authenticated标签 <shiro:authenticated> </shiro:authenticated> 用户已经身份验证通过,即Subject.login登录成功,不是记住我登录的。 notAuthenticated标签 <shiro:notAuthenticated> </shiro:notAuthenticated> 用户已经身份验证通过,即没有调用Subject.login进行登录,包括记住我自动登录的也属于未进行身份验证。 principal标签 <shiro: principal/> <shiro:principal property="username"/> 相当于((User)Subject.getPrincipals()).getUsername()。 lacksPermission标签 <shiro:lacksPermission name="org:create"> </shiro:lacksPermission> 如果当前Subject没有权限将显示body体内容。 hasRole标签 <shiro:hasRole name="admin"> </shiro:hasRole> 如果当前Subject有角色将显示body体内容。 hasAnyRoles标签 <shiro:hasAnyRoles name="admin,user"> </shiro:hasAnyRoles> 如果当前Subject有任意一个角色(或的关系)将显示body体内容。 lacksRole标签 <shiro:lacksRole name="abc"> </shiro:lacksRole> 如果当前Subject没有角色将显示body体内容。 hasPermission标签 <shiro:hasPermission name="user:create"> </shiro:hasPermission> 如果当前Subject有权限将显示body体内容