Springboot简单整合Shiro
1导入shiro需要的依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
2 编写shiro的配置类
shiro常用的过滤器, 添加内置过滤器,可以实现权限相关的的拦截器
anon: 无需认证(登录)可以访问
authc: 必须认证才可以访问
user: 如果使用rememberMe的功能可以直接访问
perms: 该资源必须得到资源权限才可以访问
role: 该资源必须得到角色权限才可以访问
需要配置三个核心方法
1.创建ShiroFilterFactoryBean
2.创建DefaultWebSecurityManager
3.创建realm
@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager" )DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
//设置登录路径
shiroFilterFactoryBean.setLoginUrl("/toLogin");
Map<String,String> filterMap = new LinkedHashMap<>();
filterMap.put("/toAdd","authc");
filterMap.put("/toUpdate","authc");
filterMap.put("/","anon");
filterMap.put("/login","anon");
filterMap.put("/toAdd","perms[user:add]");
filterMap.put("/toUpdate","perms[user:update]");
//使用shiro自带授权过滤器,当授权过滤器拦截后,shiro会自动跳转到未授权页面
shiroFilterFactoryBean.setUnauthorizedUrl("/toNoauthor");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
//创建DefaultWebSecurityManager
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
//创建realm
@Bean(name = "userRealm")
public UserRealm getRealm(){
return new UserRealm();
}
3编写自己的Reaml类
Reaml 类要继承 AuthorizingRealm 并重写其方法,去实现授权逻辑和认证逻辑
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//执行授权逻辑
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行授权逻辑");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获取登录用户的信息
Subject subject = SecurityUtils.getSubject();
User user = (User)subject.getPrincipal();
User dbuser = userService.queryById(user.getId());
//设置授权的字符串,如果未授权,或者授权的信息不匹配,将跳转到未授权页面
info.addStringPermission(dbuser.getPerms());
return info;
}
//执行认证逻辑
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行认证逻辑");
//把authenticationToken转换成UsernamePasswordToken,因为UsernamePasswordToken包含了用户的请求的信息
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
System.out.println(token);
User user = userService.queryByName(token.getUsername());
System.out.println(user);
if (user==null) {
/*
如果用户名不存在,返回空值
shiro底层会抛出UnKnowAccountException
*/
return null;
}
return new SimpleAuthenticationInfo(user,user.getPassword(), "");
}
}
4 编写Controller类实现逻辑认证操作
认证操作的时候,当执行登录方法之后,会跳转到用户自定义的Reaml类中的认证逻辑操作中去进行逻辑认证
使用shiro编写认证操作
1.获取subject
2.封装用户数据
3.执行登录方法
@PostMapping("/login")
public String login(String username, String password, Model model){
//获取subject
Subject subject = SecurityUtils.getSubject();
//封装用户数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//执行登录方法
try{
//执行登录方法之后,会跳到UserRealm去进行认证逻辑操作
subject.login(token);
//登录成功,跳转到welcome页面
model.addAttribute("username",username);
return "index";
}catch (UnknownAccountException e){
//用户名不存在
model.addAttribute("msg","用户名不存在");
return "login";
}catch (IncorrectCredentialsException e){
//密码错误
model.addAttribute("msg","密码错误");
return "login";
}
}