SpringBoot整合Shiro
一、 Shiro 官方提供的 Starter
添加 shiro-spring-boot-web-starter
,这个依赖可以代替之前的 shiro-web
和 shiro-spring
两个依赖,pom.xml 文件如下:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0</version>
</dependency>
二、配置ShiroConfig
@Configuration
public class ShiroConfig {
/**
* 设定加密算法
* @return
*/
@Bean
public HashedCredentialsMatcher credentialsMatcher(){
HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("MD5");
credentialsMatcher.setHashIterations(1903);
return credentialsMatcher;
}
/**
* 自定义Reaml
* @return
*/
@Bean
public ShiroRealm shiroRealm(){
ShiroRealm shiroRealm=new ShiroRealm();
shiroRealm.setCredentialsMatcher(credentialsMatcher());
return shiroRealm;
}
/**
* 配置SecurityManager
* @return
*/
@Bean
public DefaultWebSecurityManager securityManager(){
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
return securityManager;
}
@Autowired
private ResourcesService resourcesService;
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition(){
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
Map<String,String> map=new LinkedHashMap<>();
List<Resources> list= resourcesService.selectListByStatusAndSortNum();
for(Resources r:list){
map.put(r.getKeyurl(),r.getFiltername());
}
definition.addPathDefinitions(map);
return definition;
}
/**
* Cookie Remember Me
* @return
*/
@Bean
public CookieRememberMeManager cookieRememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
simpleCookie.setMaxAge(259200000);
cookieRememberMeManager.setCookie(simpleCookie);
cookieRememberMeManager.setCipherKey(Base64.decode("6ZmI6I2j5Y+R5aSn5ZOlAA=="));
return cookieRememberMeManager;
}
}
三、application.yml
接下来在 application.properties 中配置 Shiro 的基本信息
#shiro
shiro:
loginUrl: /login #未认证可访问的资源
successUrl: /success #认证成功访问的资源
unauthorizedUrl: /unauth #无权限访问的资源
参考(Shiro-Spring整合)
四、ShiroRealm
public class ShiroRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
认证方法
1、该方法什么时候会被调用?
Subject.login(token)
2、方法的入参是什么?
UsernamePasswordToken
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//1 得到用户名
UsernamePasswordToken upToken= (UsernamePasswordToken) token;
// upToken.getPassword();//前端输入的密码
String uname=upToken.getUsername();
// 2根据用户名查询数据库 是否存在
User user=userService.selectByUname(uname);
if(user==null){
throw new UnknownAccountException("用户名不存在");
}
if(user.getStatus()==0){
throw new LockedAccountException("该帐户因异常,暂时无法访问");
}
//3 密码的比较是由Shiro完成的
/*
身份验证:一般需要提供如身份 ID 等一些标识信息来表明登录者的身份,如提供 email,用户名/密码来证明。
在 shiro 中,用户需要提供 principals (身份)和 credentials(证 明)给 shiro,从而应用能验证用户身份:
•principals:身份,即主体的标识属性,可以是任何属性,如用户名、 邮箱等,唯一即可。
一个主体可以有多个 principals,但只有一个 Primary principals,一般是用户名/邮箱/手机号。
•credentials:证明/凭证,即只有主体知道的安全值,如密码/数字证 书等。
• 最常见的 principals 和 credentials 组合就是用户名/密码了
*/
Object principal=uname;
Object credentials=user.getUpass();// 数据库查询出的密码
String realmName=super.getName();//realm名称
//实现的方式是将每一个口令同一个叫做”盐“(salt)的n位随机数相关联。
ByteSource salt=ByteSource.Util.bytes(uname);
// SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(principal,credentials,realmName);
//SimpleAuthenticationInfo(Object principal, Object hashedCredentials, ByteSource credentialsSalt, String realmName)
SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(principal,credentials,salt,realmName);
return info;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//1 得到当前主体的用户名 lilaoshi
String uname= (String) principals.getPrimaryPrincipal();
//2 根据用户名 查询访用户拥有哪些角色
Set<String> roles=userService.selectRnamesByUname(uname);
//3 如果某个用户角色里面,只要包含了 管理员角色。那么所有的角色该用户都具备。
if(roles.contains("admin")){
//查询所有的角色,赋给该 用户
roles=userService.selectListRnamesByRole();
}
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(roles);
return info;
}
}