刚刚学习shiro,动手做了个入门demo,高手请绕道。嘻嘻
项目源码:https://github.com/cenmen/shiro-demo1.0.git
项目结构如下图:
在shiro数据库中新建两个表user和authority,表的内容如下图:
备注:demo使用springboot+ssm框架,在项目结构中的beans,mapper,service,service.impl包中的代码我就不贴出来了,也就是对数据库操作的代码,想要的可以自行下载源码看哦。
1,在pom.xml中引入shiro
org.apache.shiro
shiro-spring
1.2.3
2,配置ShiroConfiguration类
package com.liang.auth;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
@Configuration
public class ShiroConfiguration {
/*
*/
@Bean
public UserRealm userRealm() {
return new UserRealm();
}
/*
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//指定认证失败后跳转的页面
shiroFilterFactoryBean.setLoginUrl("/login.html");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index.html");
// 未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/error.html");
//配置资源的访问规则
Map filterChainDefinitionMap = new LinkedHashMap();
// 配置不会被拦截的链接 顺序判断,authc:所有url都必须认证通过才可以访问, anon:所有url都都可以匿名访问
filterChainDefinitionMap.put("/login.html", "anon");
filterChainDefinitionMap.put("/sys/login.do", "anon");
//访问authority.html需要add权限
filterChainDefinitionMap.put("/authority.html", "perms[add]");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/*
*/
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm());
return securityManager;
}
}
3,自定义Realm类:UserRealm
package com.liang.auth;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
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.springframework.beans.factory.annotation.Autowired;
import com.liang.beans.Authority;
import com.liang.beans.User;
import com.liang.service.IUserService;
public class UserRealm extends AuthorizingRealm {
@Autowired
private IUserService userService;
//执行授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("执行授权...");
User token = (User)SecurityUtils.getSubject().getPrincipal();
System.out.println(token);
String userRole = token.getRole();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//根据用户ID查询角色(role),放入到Authorization里。
Authority authority = userService.findAuthor(userRole);
Set permissionSet = new HashSet();
// String author = authority.getAuthor();
permissionSet.add(authority.getAuthor());
// info.setRoles(roleSet); //添加角色
info.setStringPermissions(permissionSet);
return info;
}
//执行认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg) throws AuthenticationException {
System.out.println("执行认证......");
UsernamePasswordToken token = (UsernamePasswordToken) arg;
String password = new String(token.getPassword());
User user = userService.findUsers(token.getUsername(), password);
//如果该方法返回AuthenticationInfo对象就代表认证成功,如果返回null就代表认证失败
if (user != null) { //登录成功
return new SimpleAuthenticationInfo(
user, //priciple,使用当前登录用户对象
password, //credentials
user.getName()); //realmName
}
return null; //返回null代表认证失败
}
}
4,在Controller层操作:UserController
package com.liang.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.liang.beans.User;
import com.liang.service.IUserService;
@RestController //就是@Controlller和@ResponseBody注解的结合
@RequestMapping("/sys")
public class UserController {
@Autowired
private IUserService userService;
@RequestMapping(path="/login.do", produces="application/json;charset=utf-8")
public Map login(String username, String password) {
Map map =new HashMap();
//第一步:创建令牌
UsernamePasswordToken token = new UsernamePasswordToken(username, password); //james , 234
//第二步:获取Subject对象,该对象封装了一系列的操作
Subject subject = SecurityUtils.getSubject();
//第三步:执行认证
try {
subject.login(token);
System.out.println("登录成功");
map.put("status", "200");
map.put("message", "登录成功");
return map;
} catch (AuthenticationException e) {
e.printStackTrace();
map.put("status", "500");
map.put("message", "登录失败");
}
return map;
}
@RequestMapping(path="/logout.do", produces="application/json;charset=utf-8")
public Map logout(HttpSession session) {
//session.removeAttribute("user"); //删除Session的user属性
//session.invalidate(); //把整个session销毁
Map map =new HashMap();
SecurityUtils.getSubject().logout();
map.put("status", "200");
map.put("message", "注销成功");
return map;
}
@RequestMapping(path="/addSession.do", produces="application/json;charset=utf-8")
public Map addSession(HttpSession session) {
session.setAttribute("session", "session");
Map map =new HashMap();
try {
userService.addSession();
map.put("status", "200");
map.put("message", "添加Session成功");
} catch (Exception e) {
e.printStackTrace();
map.put("status", "500");
map.put("message", "登录失败");
}
return map;
}
}
5,login.html
login
其他html我就不贴了,大概都差不多,就是发送请求。