这里不对shiro做详细介绍,仅仅是做一个基本功能可以用的例子供大家参考,网上例子大多详细,不能实现。
1创建4张表:
desc tb_user;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(55) | YES | | NULL | |
| password | varchar(55) | YES | | NULL | |
| isDelete | tinyint(1) | YES | | NULL | |
| createDate | date | YES | | NULL | |
+------------+-------------+------+-----+---------+----------------+
desc role;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(55) | YES | | NULL | |
| description | varchar(255) | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
desc tb_user;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(55) | YES | | NULL | |
| password | varchar(55) | YES | | NULL | |
| isDelete | tinyint(1) | YES | | NULL | |
| createDate | date | YES | | NULL | |
+------------+-------------+------+-----+---------+----------------+
desc permission;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| token | varchar(55) | YES | | NULL | |
| theurl | varchar(55) | YES | | NULL | |
| description | varchar(255) | YES | | NULL | |
| roleId | int(11) | YES | MUL | NULL | |
+-------------+--------------+------+-----+---------+----------------+
表没看懂的看实体类吧
2建立实体类:
用户:
/** * 用户 */ public class User { private int id; private String username; private String password; private boolean isDelete; private Date createDate; List<Role> userRoles;角色:
/** * 角色表 */ public class Role { private int id; private String name; private String description;权限:
/** * 权限表 */ public class Permission { private int id; private String token; private String theurl; private String description; private int roleId;3数据查询
shiro的原理是根据用户登录名去查找他是否有响应角色或者相应权利,然后角色和权利才是决定访问权限的
@Repository public interface PermissionMapper { /** * 查询一个角色的所有权限 * @param roleId * @return */ @Select("select * from permission where roleId=#{roleId}") @Results({ @Result(id=true,column = "id",property = "id"), @Result(column = "token",property = "token"), @Result(column = "theurl",property = "theurl"), @Result(column = "description",property = "description"), @Result(column = "roleId",property = "roleId") }) List<Permission> selectPermissionByRoleId(@Param("roleId") int roleId); }
@Repository public interface RoleMapper { /** * 查询一个用户的所有角色 * @param userid * @return */ @Select("select * from role where id in (select roleid from userrole where userid=#{userid})") @Results({ @Result(id=true,column = "id",property = "id"), @Result(column = "name",property = "name"), @Result(column = "description",property = "description") }) List<Role> selectByUserId(@Param("userid") int userid); }
@Repository public interface UserMapper { /** * 根据用户名查询用户的所有信息 * @param username * @return */ @Select("select * from tb_user where username=#{username}") @Results({ @Result(id = true,column = "id",property = "id"), @Result(column = "username",property = "username"), @Result(column = "password",property = "password"), @Result(column = "isDelete",property = "isDelete"), @Result(column = "createDate",property = "createDate"), @Result(column = "id",property = "userRoles", many = @Many(select="com.smart.dao.RoleMapper.selectByUserId",fetchType = FetchType.LAZY)) }) User selectUserByName(@Param("username") String username); }4服务层设计具体需要的信息,只给接口,代码的话,我会给源码:
public interface PermissionService { /** * 根据用户id找出该用户所有权限 * @param userid * @return */ List<Permission> getPermissionByUserId(int userid); /** * 根据用户名字,找出所有权限字段 * @param username * @return */ List<String> getTheUrl(String username); }
public interface RoleService { /** * 根据用户id找出用户所有角色 * @param userid * @return */ List<Role> getRoles(int userid); }
public interface UserService { User getUserByUsername(String username); }
5自定义AuthorizingRealm
@Component("myshiroReam") public class MyShiroRealm extends AuthorizingRealm { @Autowired @Qualifier("permissionService") private PermissionService permissionService; @Autowired @Qualifier("userService") private UserService userService; @Autowired @Qualifier("roleService") private RoleService roleService; protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //获取登录时输入的用户名 String username=(String) principalCollection.fromRealm(getName()).iterator().next(); if(username!=null){ List<String> listUrl=permissionService.getTheUrl(username);//权限 User user=userService.getUserByUsername(username);//用户信息 SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); if(listUrl!=null&&!listUrl.isEmpty()){ for(String url:listUrl){ info.addStringPermission(url);//加入权限 } } List<Role> roles=roleService.getRoles(user.getId()); if(roles!=null&&!roles.isEmpty()){ for(Role role:roles){ info.addRole(role.getName());//加入角色 } } return info; } return null; } protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken token=(UsernamePasswordToken)authenticationToken; //通过表单接收的用户名 String username=token.getUsername(); if(username!=null&&!"".equals(username)){ User user=userService.getUserByUsername(username); if(user!=null){ return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),getName()); } } return null; } }6配置过滤器web.xml中:
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>7配置spring配置文件:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="/toLogin"/><!--登录页面,--> <property name="successUrl" value="/success"/><!--登录成功页面,如果自己设置了返回页面,则不跳转--> <property name="unauthorizedUrl" value="/error"/> <property name="filterChainDefinitions"> <value> /toLogin=anon <!--表示都可以访问--> /login=anon /home=perms[home] <!--perms表示需要该权限才能访问的页面--> /admin=roles["admin,user"] <!--只有拥有admin角色的用户才可访问,同时需要拥有多个角色的话,用引号引起来,中间用逗号隔开--> /**=authc <!--authc表示需要认证才能访问的页面--> </value> </property> </bean> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myshiroReam"/> </bean>8控制器中设置测试:
@Controller public class LoginController { @Autowired @Qualifier("userService") private UserService userService; //跳转到登录页面 @RequestMapping(value = "/toLogin") public String toLogin(){ return "login"; } //实现用户登录 @RequestMapping(value = "/login") public ModelAndView Login(String username,String password){ ModelAndView mav=new ModelAndView(); User user=userService.getUserByUsername(username); if(user==null){ mav.setViewName("toLogin"); mav.addObject("msg","用户不存在"); } if(!user.getPassword().equals(password)){ mav.setViewName("toLogin"); mav.addObject("msg","账号密码错误"); return mav; } SecurityUtils.getSecurityManager().logout(SecurityUtils.getSubject());//如果原来有的话,就退出 //登录后存放进shiro token UsernamePasswordToken token=new UsernamePasswordToken(user.getUsername(),user.getPassword()); Subject subject=SecurityUtils.getSubject(); subject.login(token); //登录成功后会跳转到successUrl配置的链接,不用管下面返回的链接 mav.setViewName("redirect:/success"); return mav; } @RequestMapping(value = "logout") public String logout(){ SecurityUtils.getSecurityManager().logout(SecurityUtils.getSubject());//退出 return "login"; } }@Controller public class IndexController { @RequestMapping("/home") public String index(){ System.out.println("登录成功"); return "home"; } @RequestMapping("/success") public String success(){ return "success"; } @RequestMapping("/error") public String error(){ return "error"; } @RequestMapping("/admin") public String admin(){ return "admin"; } }前台页面不写了,具体代码:
https://github.com/zhanxupeng/shiro