shiro入门学习
程序目录
shiro有三大部件
1.realm:安全数据,用于授权和认证
2.SecurityManager 安全管理所有用户
3.Subject :当前对象
一般来说,使用shiro需要两个核心的类,一个是realm类(需要自己创建),一个是shiroconfig(配置类),两个类是互相调用的。
要注意的是,在设置权限的时候,参数是路由而不是文件路径
UserRealm:
package com.su.shiro.config;
import com.su.shiro.mapper.UserMapper;
import com.su.shiro.pojo.User;
import com.su.shiro.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
//AuthorizingRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授权");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Subject subject = SecurityUtils.getSubject();
User currentUser= (User) subject.getPrincipal();//拿到user对象
info.addStringPermission(currentUser.getPower());
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("认证");
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
User user=userService.getUserByUsername(userToken.getUsername());
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
}
ShiroConfig:
package com.su.shiro.config;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import sun.security.krb5.Realm;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
/**
* shiro 三大部件
* 1.subject
* 2.securityManager
* 3.realm
*/
//第一步:创建Realm
@Bean(name = "userRealm")
public UserRealm getRealm(){
return new UserRealm();
}
//第二部:创建securityManager
@Bean(name = "securityManager")
public DefaultWebSecurityManager getSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联realm
securityManager.setRealm(userRealm);
return securityManager;
}
//第三步:拦截器
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//添加shiro的过滤器
/**
* anon:无需认证就可以访问
* authc:必须认证以后才能访问
* user:必须使用记住我功能后才能使用
* perms:拥有对某个资源的权限才能访问
* role:拥有某个角色权限才能访问
*/
//拦截
Map<String,String> filterMap=new LinkedHashMap<>();
//授权,正常情况下,没有授权会跳转到未授权页面
//参数:(路由,权限要求)
filterMap.put("/toadd","authc");
filterMap.put("/toupdate","perms[1]");
bean.setFilterChainDefinitionMap(filterMap);
//关联securitymanager
bean.setSecurityManager(securityManager);
//设置登录的请求
bean.setLoginUrl("/toLogin");
//未授权页面
bean.setUnauthorizedUrl("/noauth");
return bean;
}
}
测试:
package com.su.shiro.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
@RequestMapping("/login")
public String login(String username, String password, Model model){
//获取subject对象
Subject subject= SecurityUtils.getSubject();
//封装获取到的对象
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);//执行登录方法
return "index";
}catch (UnknownAccountException e){
model.addAttribute("msg","用户名错误");
return "login";
} catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "login";
}
}
}
这里的登录也有shiro提供的方法,直接subject.login()就行了
其他地方就没什么重要的地方了
如果有什么地方写的不对,欢迎大家指正