Springboot进阶-03-Shiro
1.Springboot-Shiro
-
shiro概念
-
shiro核心功能,身份验证、授权、加密和会话管理。
-
shiro三个核心对象。Subject,用户;ShiroSecurityManager,用户管理;Realm,连接数据。
-
-
导入依赖
<!-- shiro和thymeleaf整合 -->
<!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring-boot-starter -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.7.1</version>
</dependency>
- shiro.ini
[users]
# user 'root' with password 'secret' and the 'admin' role
# 用户名 密码 角色
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
# user 'presidentskroob' with password '12345' ("That's the same combination on
# my luggage!!!" ;)), and role 'president'
presidentskroob = 12345, president
# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
# 用户名 密码 两种角色
darkhelmet = ludicrousspeed, darklord, schwartz
# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
lonestarr = vespa, goodguy, schwartz
# -----------------------------------------------------------------------------
# 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
# dev对user资源用于create权限
dev = user:create
- 日志配置
# log4j.properties
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
# General Apache libraries
log4j.logger.org.apache=WARN
# Spring
log4j.logger.org.springframework=WARN
# Default Shiro logging
log4j.logger.org.apache.shiro=INFO
# Disable verbose logging
log4j.logger.org.apache.shiro.util.ThreadContext=WARN
log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
- shiro配置类
- Realm操作数据库
public class UserRealm extends AuthorizingRealm {
@Resource
private UserServer userServer;
/**
* 授权
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 获取从数据库中查询到的权限,会保存在Subject中
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Subject subject = SecurityUtils.getSubject();
User user = (User) subject.getPrincipal();
// 从数据库中查询后,设置访问的权限
info.addStringPermission(user.getPerms());
return info;
}
/**
* 认证
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//String username = "root";
//String password = "123456";
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
/*System.out.println(usernamePasswordToken.getUsername());
if (!username.equals(usernamePasswordToken.getUsername())) {
// 当为null时,会抛出 UnknownAccountException
System.out.println("===========null");
return null;
}*/
// 从数据库查询用户信息
User user = userServer.getUser(usernamePasswordToken.getUsername());
if (user == null) {
// 当为null时,会抛出 UnknownAccountException
return null;
}
// shiro认证密码,将user对象传递
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), "");
return info;
}
}
- Shiro配置类
@Configuration
public class MyShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Autowired DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
filterFactoryBean.setSecurityManager(securityManager);
// 添加需要过滤的请求
/*
anon 无需认证就可以访问
authc 需要认证才能访问
user 需要记住我才能访问
perms 拥有对某个资源的权限才可以访问
role 拥有某个角色才能访问
*/
Map<String, String> map = new HashMap<>();
//map.put("/user01", "authc");
//map.put("/user02", "anon");
// 授权 访问/user01需要有user:user01权限
map.put("/user01", "perms[user:user01]");
map.put("/user02", "perms[user:user02]");
filterFactoryBean.setFilterChainDefinitionMap(map);
// 需要认证时进入登录页面
filterFactoryBean.setLoginUrl("/login");
// 设置授权的url
filterFactoryBean.setUnauthorizedUrl("/authentication");
return filterFactoryBean;
}
/**
* 安全管理
* @param userRealm
* @return
*/
@Bean
public DefaultWebSecurityManager securityManager(@Autowired UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
/**
* 将Realm注入容器
* @return
*/
@Bean
public UserRealm userRealm() {
return new UserRealm();
}
}