1、添加Shiro的Maven依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
2、Shiro核心操作说明
Subject 用户
SecurityManager 管理所有用户
Realm 连接数据
//当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//执行登录方法,如果没有异常就说明OK了
subject.login(token);
//退出登录
subject.logout();
//getPrincipal() 获取到的SimpleAuthenticationInfo中的第一个参数
new SimpleAuthenticationInfo(user,user.getPassword(),"");
User user= (User) subject.getPrincipal();
3、创建UserRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权认证=>doGetAuthorizationInfo");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获取当前用户对象
Subject subject = SecurityUtils.getSubject();
User user= (User) subject.getPrincipal();
//设置当前用户权限
info.addStringPermission(user.getRole());
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了登录认证=>doGetAuthenticationInfo");
//从token中获取用户输入的账号密码
UsernamePasswordToken usertocken=(UsernamePasswordToken)token;
//连接真实数据库
User user = userService.selectByName(usertocken.getUsername());
if(user==null){
//如果用户名不一样,返回null 会自动抛出异常
return null;
}
//密码认证,shiro做
//可以将user放入 Subject subject = SecurityUtils.getSubject(); 中,在授权里面获取
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
token中的账号密码来源:
//在控制器或者接收用户输入账号密码的地方使用如下代码
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
SecurityUtils.getSubject().login(token);
4、创建Shiro配置类,并设定需要拦截的请求
@Configuration
public class ShiroConfig {
//shiroFileterFactoryBean
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager manager){
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(manager);
//添加shiro的内置过滤器
/*
* anno:无需认证就可以访问
* authc:必须认证才能访问
* user:必须拥有 记住我才能用
* perms:拥有对某个资源的权限才能访问
* role:拥有某个角色的权限才能访问
* */
Map<String,String> fileter=new LinkedHashMap<String,String>();
//正常情况下未授权,会跳转到没有授权页面
fileter.put("/user/add","perms[admin]");
fileter.put("/user/update","authc");
bean.setFilterChainDefinitionMap(fileter);
//设置登录请求拦截 跳转的路径
bean.setLoginUrl("/tologin");
//未授权拦截
bean.setUnauthorizedUrl("/nopermission");
return bean;
}
//DefaultWebSecurityManager
@Bean
public DefaultWebSecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
//关联UserRealm
manager.setRealm(userRealm);
return manager;
}
//创建 realm 对象, 需要自定义
//用户认证会放到UserRealm下
//@Bean 默认情况下方法名为对象名
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
//整合ShiroDialect 用来整合:shiro thymeleaf
//getShiroDialect
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
5、Controller中的登录操作
@RequestMapping("/user/login")
public String login(String username,String password,Model model){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try{
//执行登录方法,如果没有异常就说明OK了
subject.login(token);
model.addAttribute("msg","登录成功");
return "/index";
}catch (UnknownAccountException ex){
model.addAttribute("msg","用户名错误");
return "/user/login";
}catch (IncorrectCredentialsException ex){
model.addAttribute("msg","密码错误");
return "/user/login";
}catch (Exception e){
model.addAttribute("msg","未知错误");
return "/user/login";
}
}