导入jar包
pom.xml:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
认证
创建reaml包,然后在其中创建继承AuthorizingRealm类的NewsRealm类
(1)创建setName方法,给NewsRealm类取名为newsRealm
(2)创建doGetAuthenticationInfo方法实现认证:
1.将authenticationToken强转为UsernamePasswordToken类对象token(多态);
2.通过token拿到用户名和密码;
3.调用userService的checkUser方法,得到user对象;
4.若user不为空,登录成功,将用户、密码和NewsRealm的名字赋值给new的SimpleAuthenticationInfo对象,返回该对象;
5.否则,登录失败,返回空
public class NewsRealm extends AuthorizingRealm {
public void setName(String name){
setName("newsRealm");
}
@Autowired
private UserService userService;
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
String username = token.getUsername();
String password = new String(token.getPassword());
User user = userService.checkUser(username, password);
if(user!=null){
return new SimpleAuthenticationInfo(user,password,this.getName());
}
return null;
}
}
创建ShiroConfiguration类
配置文件:配置拦截规则
(1)创建getRealm方法:将NewsRealm对象注入spring容器
(2)创建securityManager方法:统一管理NewsRealm对象
(3)创建shiroFilterFactoryBean方法:配置拦截规则
1.拦截admin下的所有请求
2.除了登录请求
3.拦截后跳转到登录界面
(4)创建authorizationAttributeSourceAdvisor方法:开启注解支持
@Configuration
public class ShiroConfiguration {
@Bean
public NewsRealm getRealm(){
return new NewsRealm();
}
@Bean
public SecurityManager securityManager(NewsRealm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/admin");
shiroFilterFactoryBean.setUnauthorizedUrl("/admin/unauthor");
Map<String,String> filterMap=new LinkedHashMap<>();
filterMap.put("/admin/login","anon");
filterMap.put("/admin/**","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager ){
AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}
在LoginController类中,改写登录方法
1、将用户名、密码传给token
2、调用SecurityUtils的getSubject方法得到subject对象
3、通过subject对象执行登录,将token传到后台realm中
4、调用subject的getPrincipal方法得到user对象
5、把user对象放进session
6、try catch捕捉异常,没有报错,登录成功,跳转到admin/index
@PostMapping("login")
public String login(String username, String password, HttpSession session, RedirectAttributes redirectAttributes){
try{
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
Subject subject= SecurityUtils.getSubject();
subject.login(token);
User user= (User) subject.getPrincipal();
session.setAttribute("user",user);
return "admin/index";
}catch (Exception e){
redirectAttributes.addFlashAttribute("message","用户名和密码错误1");
return "redirect:/admin";
}
}
授权
创建reaml包,然后在其中创建继承AuthorizingRealm类的NewsRealm类
创建doGetAuthorizationInfo方法实现授权:
1.调用principalCollection的getPrimaryPrincipal方法,得到user对象;
2.调用user的getRoles方法得到角色集合roles;
3.将roles集合里的role,循环添加到SimpleAuthorizationInfo对象info里;
4.每一次addRole之后,将role的permissions集合里的permission,循环添加到info里
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User user= (User) principalCollection.getPrimaryPrincipal();
Set<Role> roles = user.getRoles();
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
for(Role role:roles){
info.addRole(role.getName());
for(Permission p:role.getPermissions()){
info.addStringPermission(p.getCode());
}
}
return info;
}