在前面我们一起使用了iniRealm和JdbcRealm的使用,接下来我们将在web下使用自定义的Realm。
步骤一:导入jar包
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.15</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
步骤二:配置shiro.ini文件
[main]
realm=com.zmz.shiro.MyShiro
securityManager.realm=$realm
/#配置过滤器
authc=org.apache.shiro.web.filter.authc.FormAuthenticationFilter
/#定义login的路径
authc.loginUrl=/login.jsp
[urls]
/#定义那些可以使用 任意
/login.jsp=anon
/#只有authc可以进入
/main.jsp=authc
/#角色为manager可使用
/manager.jsp=authc,roles[manager]
/guest.jsp=authc,roles[guest]
/#权限为select 可使用
/select.jsp=perms[select]
/delete.jsp=perms[delete]
步骤三:编写maven的代码
entity层,这里使用easycode反向生成
//User类
@Data
public class User implements Serializable {
private static final long serialVersionUID = 530207062682414506L;
private Integer uid;
private String username;
private String password;
private String tel;
private String addr;
private Set<Role> roles;
}
//role 角色类
@Data
public class Role implements Serializable {
private static final long serialVersionUID = -24879821050530425L;
private Integer rid;
private String rname;
private String rdesc;
private Set<Permission> permissions;
}
// permission 权限类
@Data
public class Permission implements Serializable {
private static final long serialVersionUID = 386621187080762599L;
private Integer pid;
private String pname;
private String pdesc;
}
controller层
package com.zmz.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = "/login")
public class UserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
IniSecurityManagerFactory factory = new IniSecurityManagerFactory();
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
//创建令牌
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
//登入
try {
subject.login(token);
request.getRequestDispatcher("hello.jsp").forward(request,response);
} catch (AuthenticationException e) {
e.printStackTrace();
response.sendRedirect("login.jsp");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
service层
package com.zmz.service;
import com.zmz.entity.Permission;
import com.zmz.entity.Role;
import com.zmz.entity.User;
import java.util.List;
public interface UserService {
//通过账号密码进行查询
User getloginByUsername(String username,String password);
//通过用户名进行角色的查询
List<Role> getAllRolesByUsernam(String username);
//通过用户名进行权限的查询
List<Permission> getAllPermissionByUsername(String username);
}
service对应的impl层
package com.zmz.service.impl;
import com.zmz.dao.UserDao;
import com.zmz.dao.impl.UserDaoImpl;
import com.zmz.entity.Permission;
import com.zmz.entity.Role;
import com.zmz.entity.User;
import com.zmz.service.UserService;
import java.util.List;
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();
@Override
public User getloginByUsername(String username,String password) {
User user = userDao.getLoginByUsername(username,password);
return user;
}
@Override
public List<Role> getAllRolesByUsernam(String username) {
List<Role> roles = userDao.getAllRolesByUsername(username);
return roles;
}
@Override
public List<Permission> getAllPermissionByUsername(String username) {
List<Permission> permissions = userDao.getAllPermissionByUsername(username);
return permissions;
}
}
dao层
package com.zmz.dao;
import com.zmz.entity.Permission;
import com.zmz.entity.Role;
import com.zmz.entity.User;
import java.util.List;
public interface UserDao {
//通过username进行登入校验
User getLoginByUsername(String username,String password);
//通过username进行角色的查询
List<Role> getAllRolesByUsername(String username);
//通过username进行权限的查询
List<Permission> getAllPermissionByUsername(String username);
}
dao对应的impl层
package com.zmz.dao.impl;
import com.zmz.dao.UserDao;
import com.zmz.entity.Permission;
import com.zmz.entity.Role;
import com.zmz.entity.User;
import com.zmz.utils.DruidUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class UserDaoImpl implements UserDao {
private Connection conn = null;
private PreparedStatement pdst = null;
private ResultSet rs = null;
@Override
public User getLoginByUsername(String username,String password) {
conn = DruidUtil.getConnection();
User user = null;
try {
//创建sql语句
String sql = "select * from user where username=? and password = ?";
pdst = conn.prepareStatement(sql);
//添加数据
pdst.setString(1,username);
pdst.setString(2,password);
rs = pdst.executeQuery();
while(rs.next()){
user = new User();
user.setUid(rs.getInt("uid"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setAddr(rs.getString("addr"));
user.setTel(rs.getString("tel"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DruidUtil.closeAll(conn,pdst,rs);
}
return user;
}
@Override
public List<Role> getAllRolesByUsername(String username) {
conn = DruidUtil.getConnection();
List<Role> list = new ArrayList<Role>();
try {
String sql = "select r.rid,r.rname,r.rdescn" +
"from user un" +
"inner join user_role ur on u.uid = ur.uidn" +
"inner join role r on ur.rid = r.ridn" +
"where u.username = ?";
pdst = conn.prepareStatement(sql);
pdst.setString(1,username);
rs = pdst.executeQuery();
Role role = new Role();
while(rs.next()){
role.setRid(rs.getInt("rid"));
role.setRname(rs.getString("rname"));
role.setRdesc(rs.getString("rdesc"));
list.add(role);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DruidUtil.closeAll(conn,pdst,rs);
}
return list;
}
@Override
public List<Permission> getAllPermissionByUsername(String username) {
conn = DruidUtil.getConnection();
List<Permission> list = new ArrayList<>();
try {
String sql = "select p.pid,p.pname,p.pdescn" +
"from user un" +
"inner join user_role ur on u.uid = ur.uidn" +
"inner join role r on ur.rid = r.ridn" +
"inner join role_perms rp on r.rid = rp.ridn" +
"inner join permission p on rp.pid = p.pidn" +
"where u.username = ?";
pdst = conn.prepareStatement(sql);
pdst.setString(1,username);
rs = pdst.executeQuery();
Permission pn = null;
while(rs.next()){
pn = new Permission();
pn.setPid(rs.getInt("pid"));
pn.setPname(rs.getString("pname"));
pn.setPdesc(rs.getString("pdesc"));
list.add(pn);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DruidUtil.closeAll(conn,pdst,rs);
}
return list;
}
}
utils工具层
import java.io.IOException;
import java.util.Properties;
//读取db.properties
public class Env extends Properties {
private static Env env = null;
private Env(){
try {
load(getClass().getResourceAsStream("/db.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static Env getInstance(){
if (env == null){
env = new Env();
}
return env;
}
}
数据连接池
package com.zmz.utils;
import com.alibaba.druid.pool.DruidDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DruidUtil {
private static final String ENV_DRIVER = Env.getInstance().getProperty("driver");
private static final String ENV_URL = Env.getInstance().getProperty("url");
private static final String ENV_USER = Env.getInstance().getProperty("user");
private static final String ENV_PASSWORD = Env.getInstance().getProperty("password");
/**
* 创建连接
*
* @return
*/
public static Connection getConnection() {
Connection conn = null;
try {
//数据源的连接
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(ENV_DRIVER);
dataSource.setUrl(ENV_URL);
dataSource.setUsername(ENV_USER);
dataSource.setPassword(ENV_PASSWORD);
conn = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 清除资源
*
* @param conn
* @param pdst
* @param rs
*/
public static void closeAll(Connection conn, PreparedStatement pdst, ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
if (pdst != null) {
pdst.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
db.properties配置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/rbac?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
user=root
password=123456
自定义域
package com.zmz.shiro;
import com.zmz.entity.Permission;
import com.zmz.entity.Role;
import com.zmz.entity.User;
import com.zmz.service.UserService;
import com.zmz.service.impl.UserServiceImpl;
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 java.util.List;
public class MyShiro extends AuthorizingRealm {
private UserService userService = new UserServiceImpl();
/**
* 角色和权限的验证
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获取用户名
String username = getAvailablePrincipal(principalCollection).toString();
//获取角色
List<Role> roles = userService.getAllRolesByUsernam(username);
for (Role role : roles) {
//添加角色
info.addRole(role.getRname());
}
//获取权限
List<Permission> permissions = userService.getAllPermissionByUsername(username);
for (Permission permission : permissions) {
//添加权限
info.addStringPermission(permission.getPname());
}
return info;
}
/**
* 用户登入的验证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
AuthenticationInfo info = null;
//将令牌转换成usernamePasswordtoken
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//获取账号和密码
String username = token.getUsername();
char[] str = token.getPassword();
String password = new String(str);
//进行用户判断
User user = userService.getloginByUsername(username, password);
if (user != null && user.getUid()!= 0){
System.out.println(getName());
info = new SimpleAuthenticationInfo(username,password,getName());
}
return info;
}
}
前端就简单的写一个表单就可以了这里随意发挥,这里就附图吧,估计看代码都烦了
![2e7217a984f462814618e67bc31d5714.png](https://i-blog.csdnimg.cn/blog_migrate/f9ef4380fc967dca90e1cf9128f6af83.png)
简单的前端shiro标签
![4ffe23ac9ed98bdaa7ff19b7091fa5c7.png](https://i-blog.csdnimg.cn/blog_migrate/1ed578c3dd09997372eb0402d5dbedc3.jpeg)
结果验证
![27a1584b697db35a72ce57c5afa7d7a9.png](https://i-blog.csdnimg.cn/blog_migrate/14ed5cb53d18eee86eb5145dd98064bf.png)