在实际开发中,我们都是操作数据库进行数据操作
我们今天不在用默认realm,用自己定义的Realm来实现
在数据库中创建三张表
t_role角色表
t_user角色表 外键关联t_role 一个用户可能有多个角色
t_premission权限表 外键关联t_role 一个角色可能有多个权限
创建一个Maven项目
自己创建一个动态web项目
把创建好的项目 web.xml index.jsp替换掉,再把META-INF文件夹贴到对应的目录下
在pom.xml贴上依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- 添加servlet支持 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- 添加jstl支持 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 添加日志支持 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- 添加shiro支持 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
</dependencies>
在web.xml贴上相关配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>ShrioWeb</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<!-- 添加shiro支持 -->
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>com.java1234.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>adminServlet</servlet-name>
<servlet-class>com.java1234.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>adminServlet</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
</web-app>
在WEB-INF下创建shiro.ini文件 已经指定我们的realm --->MyRealm
[main]
authc.loginUrl=/login
roles.unauthorizedUrl=/unauthorized.jsp
perms.unauthorizedUrl=/unauthorized.jsp
myRealm=com.gcx.realm.MyRealm
securityManager.realms=$myRealm
[urls]
/login=anon
/admin*=authc
/student=roles[teacher]
/teacher=perms["user:create"]
package com.java1234.realm;
import java.sql.Connection;
import javax.security.sasl.AuthenticationException;
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 com.java1234.dao.UserDao;
import com.java1234.entity.User;
import com.java1234.util.DbUtil;
import sun.net.www.protocol.http.AuthenticationInfo;
public class MyRealm extends AuthorizingRealm{
private UserDao userDao=new UserDao();
private DbUtil dbUtil=new DbUtil();
/**
* 为当前登录的用户授予角色和权限
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String userName=(String)principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
Connection con=null;
try{
con=dbUtil.getCon();
authorizationInfo.setRoles(userDao.getRoles(con,userName));
authorizationInfo.setStringPermissions(userDao.getPermissions(con,userName));
}catch(Exception e){
e.printStackTrace();
}finally{
try {
dbUtil.closeCon(con);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return authorizationInfo;
}
/**
* 验证当前登录的用户
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName=(String)token.getPrincipal();
Connection con=null;
try{
con=dbUtil.getCon();
User user=userDao.getByUserName(con, userName);
if(user!=null){
//内部会进行用户名密码对比
AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),"xx");
return authcInfo;
}else{
return null;
}
}catch(Exception e){
e.printStackTrace();
}finally{
try {
dbUtil.closeCon(con);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
}
验证成功后会到MyRealm类中doGetAuthorizationInfo方法,开始为当前用户授予权限与角色
package com.java1234.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
public class LoginServlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("login doget");
req.getRequestDispatcher("login.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("login dopost");
String userName=req.getParameter("userName");
String password=req.getParameter("password");
Subject subject=SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken(userName, password);
try{
//会去自定义realm获取数据
subject.login(token);
Session session=subject.getSession();
System.out.println("sessionId:"+session.getId());
System.out.println("sessionHost:"+session.getHost());
System.out.println("sessionTimeout:"+session.getTimeout());
session.setAttribute("info", "session的数据");
resp.sendRedirect("success.jsp");
}catch(Exception e){
e.printStackTrace();
req.setAttribute("errorInfo", "用户名或者密码错误");
req.getRequestDispatcher("login.jsp").forward(req, resp);
}
}
}
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="login" method="post">
userName:<input type="text" name="userName"/><br/>
password:<input type="password" name="password"/><br/>
<input type="submit" value="登录"/>${errorInfo }
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
${info }
欢迎你!
<shiro:hasRole name="admin">
欢迎有admin角色的用户!<shiro:principal/>
</shiro:hasRole>
<shiro:hasPermission name="student:create">
欢迎有student:create权限的用户!<shiro:principal/>
</shiro:hasPermission>
</body>
</html>
unauthorized.jsp 认证失败页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
认证未通过,或者权限不足
</body>
</html>
User实体:
package com.java1234.entity;
public class User {
private Integer id;
private String userName;
private String password;
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;
}
}
UserDao:
package com.java1234.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashSet;
import java.util.Set;
import com.java1234.entity.User;
public class UserDao {
public User getByUserName(Connection con,String userName)throws Exception{
User resultUser=null;
String sql="select * from t_user where userName=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1, userName);
ResultSet rs=pstmt.executeQuery();
if(rs.next()){
resultUser=new User();
resultUser.setId(rs.getInt("id"));
resultUser.setUserName(rs.getString("userName"));
resultUser.setPassword(rs.getString("password"));
}
return resultUser;
}
public Set<String> getRoles(Connection con, String userName) throws Exception{
Set<String> roles=new HashSet<String>();
String sql="select * from t_user u,t_role r where u.roleId=r.id and u.userName=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1, userName);
ResultSet rs=pstmt.executeQuery();
while(rs.next()){
roles.add(rs.getString("roleName"));
}
return roles;
}
public Set<String> getPermissions(Connection con, String userName)throws Exception {
Set<String> permissions=new HashSet<String>();
String sql="select * from t_user u,t_role r,t_permission p where u.roleId=r.id and p.roleId=r.id and u.userName=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1, userName);
ResultSet rs=pstmt.executeQuery();
while(rs.next()){
permissions.add(rs.getString("permissionName"));
}
return permissions;
}
}
DBUtil:
package com.java1234.util;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* 数据库工具类
* @author
*
*/
public class DbUtil {
/**
* 获取数据库连接
* @return
* @throws Exception
*/
public Connection getCon() throws Exception{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/db_shiro", "root", "123456");
return con;
}
/**
* 关闭数据库连接
* @param con
* @throws Exception
*/
public void closeCon(Connection con)throws Exception{
if(con!=null){
con.close();
}
}
public static void main(String[] args) {
DbUtil dbUtil=new DbUtil();
try {
dbUtil.getCon();
System.out.println("数据库连接成功");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("数据库连接失败");
}
}
}
登陆成功后,从库里取出该用户的角色权限,并为用户设置上,就可以进行后续操作了!!!!