maven坐标:
<!-- shiro 坐标 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- servlet,jsp 坐标 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
配置 web.xml
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<!-- 默认加载 WEB-INF/shiro.ini 文件, 如果需要修改路径 -->
<context-param>
<param-name>shiroConfigLocations</param-name>
<param-value>classpath:shiro.ini</param-value>
</context-param>
<!-- 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>
建立自定义 Realm,编写认证和授权方法:
public class MyRealm extends AuthorizingRealm{
//授权方法:获取授权信息
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行授权方法...");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//添加资源授权码
info.addStringPermission("product:add");
//添加角色授权码
info.addRole("admin");
return info;
}
//认证方法:获取认证信息
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行授权方法...");
//1.获取用户输入的账户信息
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
//模拟数据库的密码
String name = "jack";
String password = "1234";
if(!token.getUsername().equals(name)){
//用户不存在
return null;
}
//返回密码
return new SimpleAuthenticationInfo(name,password,"");
}
}
配置 shiro.ini:
shiro 的 web 内置过滤器, shiro 自己提供一些专门用于认证, 授权的过滤器。
shiro 分为两种过滤器:
1)认证过滤器
- anon: 用户不需要认证也可以访问
- authc: 用户必须认证才可以访问
- user: 用户只要 rememberMe,就可以访问
2) 授权过滤器
- perms: 基于资源的授权过滤器
- roles : 基于角色的授权过滤器
[main]
perms.unauthorizedUrl=/unauth.jsp
roles.unauthorizedUrl=/unauth.jsp
myRealm=com.shiro.realms.MyRealm
securityManager.realm=$myRealm
[urls]
/product/list.jsp=anon
/login=anon
/product/add.jsp=perms[product:add]
/product/update.jsp=roles[admin]
/**=authc
登陆页面:
<%@ 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>登录页面</title>
</head>
<body>
<h3>用户登录</h3>
<font color="red">${msg}</font>
<form method="post" action="${pageContext.request.contextPath}/login">
用户名:<input type="text" name="name"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登录">
</form>
</body>
</html>
编写 LoginServlet:
public class LoginServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置请求编码
request.setCharacterEncoding("utf-8");
//2.接收用户名和密码
String name = request.getParameter("name");
String password = request.getParameter("password");
//3.调用login方法
//3.1 获取Subject
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken(name, password);
try {
subject.login(token);
//获取Principal
String dbName = (String)subject.getPrincipal();
//把用户信息存储到session
request.getSession().setAttribute("userName", name);
//登录成功
response.sendRedirect(request.getContextPath()+"/index.jsp");
} catch (UnknownAccountException e) {
request.setAttribute("msg", "用户名不存在");
request.getRequestDispatcher("/login.jsp").forward(request, response);
} catch (IncorrectCredentialsException e) {
request.setAttribute("msg", "密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}