一,shiro简介
维基百科:Apache Shiro(读作“sheeroh”,即日语“城”)是一个开源安全框架,提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用,同时也能提供健壮的安全性。
二,快速搭建
1. 导包(利用Maven)
1.4.0-RC2
org.apache.shiro
shiro-core
${shiro.version}
org.apache.shiro
shiro-web
${shiro.version}
org.apache.shiro
shiro-spring
${shiro.version}
2.建表(数据库采用myBatis)
create table `t_user` (
`id` int (11),
`userName` varchar (60),
`password` varchar (300),
`roleId` int (11)
);
insert into `t_user` (`id`, `userName`, `password`, `roleId`) values('1','ayue','123456','1');
insert into `t_user` (`id`, `userName`, `password`, `roleId`) values('2','aaa','12345','2');
insert into `t_user` (`id`, `userName`, `password`, `roleId`) values('3','bbb','12345',NULL);
insert into `t_user` (`id`, `userName`, `password`, `roleId`) values('4','ccc','12345',NULL);
create table `t_role` (
`id` int (11),
`roleName` varchar (60)
);
insert into `t_role` (`id`, `roleName`) values('1','admin');
insert into `t_role` (`id`, `roleName`) values('2','teacher');
create table `t_permission` (
`id` int (11),
`permissionName` varchar (150),
`roleId` int (11)
);
insert into `t_permission` (`id`, `permissionName`, `roleId`) values('1','user:*','1');
insert into `t_permission` (`id`, `permissionName`, `roleId`) values('2','student:*','2');
3.建立3个实体类
package domain;
/**
* Created by 越 on 2017/4/4.
*/
public class User {
private Integer id;
private String userName;
private String password;
private Integer roleId;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
}
package domain;
/**
* Created by 越 on 2017/4/4.
*/
public class Role {
private int id;
private String roleName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
}
package domain;
/**
* Created by 越 on 2017/4/4.
*/
public class Permission {
private int id;
private String permissionName;
private int roleId;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPermissionName() {
return permissionName;
}
public void setPermissionName(String permissionName) {
this.permissionName = permissionName;
}
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
}
4. 配置UserMapper.xml
id, username, password,roleId
5. 建立自定义的MyRealm类:用于处理自己的业务逻辑
package shiro;
import domain.User;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import service.UserService;
import javax.annotation.Resource;
import java.util.Set;
/**
* Created by 越 on 2017/4/5.
*/
public class MyRealm extends AuthorizingRealm{
@Resource
private UserService userService;
/**
* 用于权限的认证
* @param principalCollection
* @return
*/
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String username = principalCollection.getPrimaryPrincipal().toString();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo() ;
Set roleName = userService.findRoles(username);
Set permissions = userService.findPermissions(username);
info.setRoles(roleName);
info.setStringPermissions(permissions);
return info;
}
/**
* 登录验证(先执行)
* @param token
* @return
* @throws AuthenticationException
*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 获取用户账号
String username = token.getPrincipal().toString();
// 从数据库中查询用户信息
User user = userService.findUserByUsername(username);
if (user != null){
// 将查询到的用户名和密码存放到authenticationInfo用于后面的权限判断。第三个参数传入realName。
System.out.println(getName());
AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),getName());
return authenticationInfo;
}else
return null;
}
}
6. 与SSM整合
关于如何搭建SSM框架:SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
1. 配置spring-mybatis.xml
/user/loginAdmin=anon
/user/admin*=authc
/user/student=roles[teacher]
/user/teacher=perms["user:create"]
2. UserController
package controller;
import domain.User;
import org.apache.shiro.SecurityUtils;
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;
import service.UserService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
/**
* Created by 越 on 2017/3/29.
*/
@Controller
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@RequestMapping("/loginAdmin")
public String login(User user,Model model){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(),user.getPassword());
try{
subject.login(token);
return "admin";
}catch (Exception e){
model.addAttribute("error","用户名或密码错误!");
return "login";
}
}
@RequestMapping("/admin")
public String admin(){
return "admin";
}
@RequestMapping("/student")
public String student(){
return "student";
}
@RequestMapping("/teacher")
public String teacher(){
return "teacher";
}
}
3. 页面
login.jsp
<%--
Created by IntelliJ IDEA.
User: 越
Date: 2017/4/8
Time: 15:03
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
登录页面
admin.jsp
<%--
Created by IntelliJ IDEA.
User: 越
Date: 2017/3/29
Time: 17:09
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
后台
<%--具有admin角色才会显示标签内的信息。--%>
这是admin角色登录:
<%--用户拥有user:create这个权限才回显示--%>
有user:create权限信息
登录成功
teacher.jsp
<%--
Created by IntelliJ IDEA.
User: 越
Date: 2017/4/8
Time: 16:50
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
教师
访问teacher成功
student.jsp
<%--
Created by IntelliJ IDEA.
User: 越
Date: 2017/4/8
Time: 16:50
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
学生
访问student成功
nopower.jsp
<%--
Created by IntelliJ IDEA.
User: 越
Date: 2017/4/8
Time: 15:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
权限认证失败
权限认证失败
4. web.xml
shiroFilter
org.springframework.web.filter.DelegatingFilterProxy
targetFilterLifecycle
true
shiroFilter
/*
7. 演示
-
登录:
-
因为ayue是admin角色,且拥有user:create权限,故进入后台页面:
-
访问/user/teacher
-
访问/user/student
3和4的原因在于在spring-mybatis.xml中我们的配置:
/user/student=roles[teacher]
/user/teacher=perms["user:create"]
参考资料:SSM(三)Shiro使用详解