
Shiro
AI-摘要
切换
鸡哔你 GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
Roles with assigned permissions
Each line conforms to the format defined in the
org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
-----------------------------------------------------------------------------
[roles]
'admin' role has all permissions, indicated by the wildcard '*'
admin = *
The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
license plate 'eagle5' (instance specific id)
goodguy = winnebago:drive:eagle5
### 3.quickstrat
```java
public class Quickstart {
private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
public static void main(String[] args) {
//创建具有配置的领域,用户,角色和权限的Shiro SecurityManager的最简单方法是使用简单的INI配置。
//我们将通过使用可以摄取.ini文件并//返回SecurityManager实例的工厂来做到这一点:
// 在类路径的根目录下使用shiro.ini文件
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//获取档当前的用户对象
Subject currentUser = SecurityUtils.getSubject();
//通过当前对象拿到Shiro的session,存值取值
Session session = currentUser.getSession();
session.setAttribute("someKey", "aValue");
String value = (String) session.getAttribute("someKey");
if (value.equals("aValue")) {
log.info("Retrieved the correct value! [" + value + "]");
}
// 测试当前的用户是否被认证
if (!currentUser.isAuthenticated()) {
//根据用户的账号密码生成Token
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
//记住我
token.setRememberMe(true);
try {
//执行登录
currentUser.login(token);
} catch (UnknownAccountException uae) {
//账户 UnknownAccountException
log.info("There is no user with username of " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
//密码 IncorrectCredentialsException
log.info("Password for account " + token.getPrincipal() + " was incorrect!");
} catch (LockedAccountException lae) {
//用户被锁定 LockedAccountException
log.info("The account for username " + token.getPrincipal() + " is locked. " +
"Please contact your administrator to unlock it.");
} catch (AuthenticationException ae) {
//unexpected condition? error?
}
}
//say who they are:
//print their identifying principal (in this case, a username):
log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
//test a role:
//测试角色
if (currentUser.hasRole("schwartz")) {
log.info("May the Schwartz be with you!");
} else {
log.info("Hello, mere mortal.");
}
//test a typed permission (not instance-level)
//测试类型化的权限(不是实例级别)
if (currentUser.isPermitted("lightsaber:wield")) {
log.info("You may use a lightsaber ring. Use it wisely.");
} else {
log.info("Sorry, lightsaber rings are for schwartz masters only.");
}
//a (very powerful) Instance Level permission:
//(非常强大的)实例级别权限
if (currentUser.isPermitted("winnebago:drive:eagle5")) {
log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " +
"Here are the keys - have fun!");
} else {
log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
}
//all done - log out!
currentUser.logout();
System.exit(0);
}
}
4.核心对象
1/ Subject 用户
2/ SecurityManager 管理所有用户
3/Realm 连接数据
//获得当前用户的对象
Subject currentUser = SecurityUtils.getSubject();;
//通过当前对象拿到Shiro的session,存值取值
Session session = currentUser.getSession();
//判断当前用户是否被认证
currentUser.isAuthenticated()
//获得当前用户的认证
currentUser.getPrincipal()
//拥有什么角色
currentUser.hasRole("schwartz")
//获得当前用户的权限
currentUser.isPermitted("lightsaber:wield")
##Spring boot整合Shiro示例:
###1.加入整合依赖
<!--Thymeleaf-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
<!--Shi肉整合Spring-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
2.Shi肉Config
/**
* @author 李phCode
* @create 2020 -11 -17 15:25
* 关联关系:B依赖A C依赖B
*/
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean C
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
return shiroFilterFactoryBean;
}
//DefaultWebSecurityManager B
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getUserRealm") UserRealm userRealm) {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//关联
defaultWebSecurityManager.setRealm(userRealm);
return defaultWebSecurityManager;
}
//创建Realm对象 A
@Bean
public UserRealm getUserRealm() {
return new UserRealm();
}
}
3.UserRealm
/**
* @author 李ph Code
* @create 2020 -11 -17 15:26
* 为了Shi肉Config的创建Realm创建
*/
public class UserRealm extends AuthorizingRealm {
/**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("doGetAuthorizationInfo = 执行了");
return null;
}
/**
* 认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("认证 doGetAuthenticationInfo=执行了");
return null;
}
}
4.实现登录拦截
//ShiroFilterFactoryBean C
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
//实现登录拦截
//添加Shiro的内置过滤器
/*
* anno: 无需认证就可访问
* authc: 必须认证才能访问
* user: 必须开启 记住我 才能访问
* perms: 必须拥有某个资源的权限才能访问
* role: 必须拥有某个角色的权限才能访问
* */
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//filterChainDefinitionMap.put("/user/add", "authc");
//filterChainDefinitionMap.put("/user/update", "authc");
//也可以使用通配符路径 user下的所有页面
filterChainDefinitionMap.put("/user/*", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
//如果没有权限 就去登陆 就是Controller跳转到登录的路径
shiroFilterFactoryBean.setLoginUrl("/toLogin");
return shiroFilterFactoryBean;
}
用户认证登录
Controller:
/**
* 登录认证
*/
@RequestMapping("/login")
public String login(String username, String password, Model model) {
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登陆数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//此时可以设置记住我
//token.setRememberMe(true);
//这一步直接登录 底层验证 没有异常就是成功
try {
//执行登录
subject.login(token);
return "index";
} catch (UnknownAccountException uae) {
//账户 用户名不存在 UnknownAccountException
System.out.println("There is no user with username of " + token.getPrincipal());
model.addAttribute("lrg", "用户名不存在");
return "login";
} catch (IncorrectCredentialsException ice) {
//密码 IncorrectCredentialsException
System.out.println("Password for account " + token.getPrincipal() + " was incorrect!");
model.addAttribute("lrg", "密码错误");
return "login";
} catch (LockedAccountException lae) {
//用户被锁定 LockedAccountException
System.out.println("The account for username " + token.getPrincipal() + " is locked. " +
"Please contact your administrator to unlock it.");
model.addAttribute("lrg", "用户被锁定");
return "login";
} catch (AuthenticationException ae) {
//unexpected condition? error?
model.addAttribute("lrg", "异常");
return "login";
}
}
Realem
/**
* 认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("认证 doGetAuthenticationInfo=执行了");
//设置用户名 密码
String name = "lph";
String password = "0000";
//得到登录的信息-
UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
//判断是账号否和数据库的一致
if (!userToken.getUsername().equals(name)) {
//默认抛出异常,UnknownAccountException
return null;
}
/**
* 验证密码 Shiro做的 SimpleAuthenticationInfo是AuthenticationInfo的实现
* SimpleAuthenticationInfo("获取当前用户的认证","密码","认证名")
* */
return new SimpleAuthenticationInfo("", password, "");
}
Shiro整合MyBatis
1.pom
<!--Shiro整合MB书数据库查询登录-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--日志-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
2.mapper....
/**
* @author 李phCode
* @create 2020 -11 -17 16:59
*/
@Repository
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE username=#{name}")
User queryUserByName(String name);
}
3.Controller不动 Realme
/**
* 认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("认证 doGetAuthenticationInfo=执行了");
//得到登录的信息-
UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
//拿到输入的用户名
User user = userService.queryUserByName(userToken.getUsername());
//判断是账号否和数据库的一致 空指针是调用方法或者属性的时候才会有
if (user == null) {
//默认抛出异常,UnknownAccountException
return null;
}
/**
* 验证密码 Shiro做的 SimpleAuthenticationInfo是AuthenticationInfo的实现
* SimpleAuthenticationInfo("获取当前用户的认证","密码","认证名")
* */
return new SimpleAuthenticationInfo("", user.getPassword(), "");
}
Shiro请求授权实现
Unauthorized, status=401). //未授权
1.数据库加权限字段
id u p r
1 lph 0000 user:add
2 root root user:*
3 update 0000 user:update
2.UserRealm
/**
* @author 李phCode
* @create 2020 -11 -17 15:26
* 为了Shi肉Config的创建Realm创建
*/
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("doGetAuthorizationInfo = 执行了");
//授权
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//拿到当前登录的用户对象
Subject subject = SecurityUtils.getSubject();
//取得这个值就是 认证AuthenticationInfo 里得到的用户对象
User currentUser = (User) subject.getPrincipal();
//设置用户权限 数据库用户是什么权限 那就是什么权限 getPerms就是用户的权限
info.addStringPermission(currentUser.getPerms());
return info;
}
/**
* 认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("认证 doGetAuthenticationInfo=执行了");
//得到登录的信息-
UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
//拿到输入的用户名
User user = userService.queryUserByName(userToken.getUsername());
//判断是账号否和数据库的一致 空指针是调用方法或者属性的时候才会有
if (user == null) {
//默认抛出异常,UnknownAccountException
return null;
}
/**
* 验证密码 Shiro做的 SimpleAuthenticationInfo是AuthenticationInfo的实现
* SimpleAuthenticationInfo("获取当前用户的认证","密码","认证名")
* */
return new SimpleAuthenticationInfo(user, user.getPassword(), "");
}
}
3.ShiroConfig
/**
* @author 李phCode
* @create 2020 -11 -17 15:25
* 关联关系:B依赖A C依赖B
*/
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean C
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
//实现登录拦截
//添加Shiro的内置过滤器
/*
* anno: 无需认证就可访问
* authc: 必须认证才能访问
* user: 必须开启 记住我 才能访问
* perms: 必须拥有某个资源的权限才能访问
* role: 必须拥有某个角色的权限才能访问
* */
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//授权 访问路径 权限
//正常会跳转到提示未授权页面 设置add必须有 user:add 的权限才能访问
filterChainDefinitionMap.put("/user/add", "perms[user:add]");
filterChainDefinitionMap.put("/user/update", "perms[user:update]");
//有user:*的能访问user下的所有
filterChainDefinitionMap.put("/user/*", "perms[user:*]");
//filterChainDefinitionMap.put("/user/add", "authc");
//filterChainDefinitionMap.put("/user/update", "authc");
//也可以使用通配符路径 所有的页面都需要登录
filterChainDefinitionMap.put("/user/*", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
//如果没有权限 就去登陆
shiroFilterFactoryBean.setLoginUrl("/toLogin");
//未授权
shiroFilterFactoryBean.setUnauthorizedUrl("/noauth");
return shiroFilterFactoryBean;
}
//DefaultWebSecurityManager B
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getUserRealm") UserRealm userRealm) {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//关联
defaultWebSecurityManager.setRealm(userRealm);
return defaultWebSecurityManager;
}
//创建Realm对象 A
@Bean
public UserRealm getUserRealm() {
return new UserRealm();
}
}
Shiro整合Thymeleaf
1.pom依赖
<!--Shiro整合thymeleaf-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2.在Shi肉Config中添加到Bean中
//Shiro整合thymeleaf
@Bean
public ShiroDialect getShiroDialect() {
return new ShiroDialect();
}
3.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<p th:text="${msg}"></p>
<br>
<shiro:hasPermission name="user:add">
<a th:href="@{/user/add}">add</a><br>
</shiro:hasPermission>
<shiro:hasPermission name="user:update">
<a th:href="@{/user/update}">update</a>
</shiro:hasPermission>
</body>
</html>
本文是原创文章,采用CC BY-NC-ND4.0协议,完整转载请注明来自蒲公英阁
评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果