【笔记】Shiro学习笔记

前言

Shiro框架学习笔记

添加依赖

1
2
3
4
5
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.6.0</version>
</dependency>

Shiro配置类

  • 也可以在配置文件进行配置

  • 新建一个类作为Shiro的配置类,并由@Configuration注解标注

1
2
3
4
@Configuration
public class SpringShiroConfig {
...
}

Shiro核心配置对象

  • 在配置类中创建配置Shiro核心对象的方法,并交给Spring管理
1
2
3
4
5
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
return securityManager;
}

Shiro访问规则配置

  • 在配置类中创建配置Shiro访问规则的方法,配置匿名访问的资源和认证的访问的资源,并交给Spring管理

Shiro中默认过滤器

anon:允许匿名访问
authc:需要认证后访问
logout:退出过滤器,一旦执行了退出操作,底层会将系统服务端存储的用户信息进行清除并且直接跳转到登陆页面

**:表示当前目录所有文件及其所有子目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Bean
public ShiroFilterFactoryBean shiroFilterFactory( SecurityManager securityManager){

ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
// securityManager对象负责去检测这个请求是否已经认证
factoryBean.setSecurityManager(securityManager);
// 配置登陆页面的访问路径
factoryBean.setLoginUrl("/doLoginUI");

Map<String,String> filterMap=new LinkedHashMap<>();
// 配置允许匿名访问的资源(通常为所有的静态资源)
filterMap.put("/build/**","anon");
// 配置登陆
filterMap.put("/user/doLogin","anon");
// 配置退出
filterMap.put("/doLogout","logout");

// 除了匿名访问的资源,其它都要认证后访问
filterMap.put("/**","authc");

factoryBean.setFilterChainDefinitionMap(filterMap);//过滤链的定义

return factoryBean;

}

实现认证

创建Realm类

  • service.impl包下创建一个Realm类,继承AuthorizingRealm类并重写抽象方法,为这个类标注@Component注解定义为组建交给Spring管理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Component
public class ShiroUserRealm extends AuthorizingRealm {

// 获取并封装授权信息(做授权业务时写此方法)
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}

// 获取并封装认证信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 获取登录时输入的用户名
UsernamePasswordToken uToken = (UsernamePasswordToken) authenticationToken;
String username = uToken.getUsername();

// 基于用户名查询数据库中的用户信息
SysUser user = sysUserDao.findUserByUserName(username);

// 校验用户是否存在
if (user == null) throw new UnknownAccountException();
// 校验用户是否已被禁用
if (user.getValid() == 0) throw new LockedAccountException();

// 封装用户信息由底层进行密码校验
ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());

return new SimpleAuthenticationInfo(user,//principal 身份
user.getPassword(),//hashedCredentials 已加密的密码
credentialsSalt,//credentialsSalt 凭证盐
getName());
}

}

对用户输入的密码进行加密

  • 重写getCredentialsMatcher方法或setCredentialsMatcher方法其中一个,用于返回凭证加密对象,基于此对象对用户输入的密码进行加密操作

重写getCredentialsMatcher方法

1
2
3
4
5
6
7
8
9
@Override
public CredentialsMatcher getCredentialsMatcher() {
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
// 定义加密类型
credentialsMatcher.setHashAlgorithmName("MD5");
// 定义加密次数
credentialsMatcher.setHashIterations(1);
return credentialsMatcher;
}

重写getCredentialsMatcher方法

1
2
3
4
5
6
7
8
9
@Override
public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
HashedCredentialsMatcher cMatcher = new HashedCredentialsMatcher();
// 定义加密类型
cMatcher.setHashAlgorithmName("MD5");
// 定义加密次数
cMatcher.setHashIterations(1);
super.setCredentialsMatcher(cMatcher);
}

将Realm添加到配置类

1
2
3
4
5
6
@Bean
public SecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager sManager = new DefaultWebSecurityManager();
sManager.setRealm(realm);
return sManager;
}

实现授权

在配置类配置授权检测顾问

1
2
3
4
5
6
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}

Shiro配置缓存(Cache)

在配置类配置缓存

1
2
3
4
@Bean
public CacheManager shiroCacheManager(){
return new MemoryConstrainedCacheManager();
}

将Cache配置添加到核心对象

1
2
3
4
5
6
@Bean
public SecurityManager securityManager(CacheManager cacheManager) {
DefaultWebSecurityManager sManager = new DefaultWebSecurityManager();
sManager.setCacheManager(cacheManager);
return sManager;
}

实现记住我

在配置类配置记住我

1
2
3
4
5
6
7
8
@Bean
public RememberMeManager rememberMeManager() {
CookieRememberMeManager cManager = new CookieRememberMeManager();
SimpleCookie cookie=new SimpleCookie("rememberMe");
cookie.setMaxAge(7*24*60*60);
cManager.setCookie(cookie);
return cManager;
}

在核心对象配置记住我

1
2
3
4
5
6
@Bean
public SecurityManager securityManager(RememberMeManager rememberManager) {
DefaultWebSecurityManager sManager = new DefaultWebSecurityManager();
sManager.setRememberMeManager(rememberManager);
return sManager;
}

修改访问规则

1
2
//filterMap.put("/**","authc");
filterMap.put("/**","user");

配置会话(Session)

在配置类配置会话

1
2
3
4
5
6
@Bean  
public SessionManager sessionManager() {
DefaultWebSessionManager sManager = new DefaultWebSessionManager();
sManager.setGlobalSessionTimeout(60*60*1000);
return sManager;
}

将Session配置添加到核心配置对象

1
2
3
4
5
6
@Bean
public SecurityManager securityManager(SessionManager sessionManager) {
DefaultWebSecurityManager sManager = new DefaultWebSecurityManager();
sManager.setSessionManager(sessionManager);
return sManager;
}

完成