在本例子中使用Apache Shiro在Web应用中实现身份认证,将Shiro与spring进行集成,使用内嵌的derby数据库存储用户信息。
持久层为hibernate,数据库连接池为alibaba druid。
2. 准备
创建一个内嵌的derby数据库,本例使用的是db-derby-10.10.1.1。
2.1 建表
Create table users(
Id int primary key,
Name varchar(20),
Passwd varchar(20)
);
2.2 初始化数据
Insert into users values(1,’admin’,’admin’);
Insert into users values(2,’peter’,’peter’);
3. 配置
3.1 Web.xml
- <!-- Apache Shiro -->
- <filter>
- <filter-name>shiroFilter</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- <init-param>
- <param-name>targetFilterLifecycle</param-name>
- <param-value>true</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>shiroFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
3.2 ApplicationContext.xml
- <!-- 安全认证过滤器 -->
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <property name="securityManager" ref="securityManager" />
- <property name="loginUrl" value="/index.do" />
- <property name="filterChainDefinitions">
- <value>
- /login.do = anon
- /** = authc
- </value>
- </property>
- </bean>
- <!-- 定义 Shiro 主要业务对象 -->
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="systemAuthorizingRealm" />
- </bean>
- <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
- <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
4. 认证
登录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>Login</title>
- </head>
- <body>
- <form id="form1" name="form1" method="post" action="login.do">
- <p align="center">用户登录</p>
- <table width="296" border="1" align="center" bgcolor="#00FF99">
- <tr>
- <td width="98" height="34">用户名:</td>
- <td width="182"><label><input name="loginName"
- type="text" id="loginName" /> </label></td>
- </tr>
- <tr>
- <td height="36">密码:</td>
- <td><label> <input name="password" type="password"
- id="password" />
- </label></td>
- </tr>
- <tr>
- <td height="35" colspan="2"><label>
- <input type="submit" name="Submit" value="提交" />
- </label> <label> <input
- type="reset" name="Submit2" value="重置" />
- </label></td>
- </tr>
- </table>
- </form>
- </body>
- </html>
Web控制器
- @Controller
- public class LoginController {
- private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);
- @RequestMapping(value = "/login.do", method = RequestMethod.POST)
- public String isLogin(HttpServletRequest request, PasswordAuthcInfo passwordAuthcInfo) {
- String loginName = passwordAuthcInfo.getLoginName();
- String loginPassword = passwordAuthcInfo.getPassword();
- LOGGER.info("loginName:" + loginName + ";loginPassword:" + loginPassword);
- HttpSession session = request.getSession(true);
- String errorMessage = "";
- Subject user = SecurityUtils.getSubject();
- UsernamePasswordToken token = new UsernamePasswordToken(loginName, loginPassword);
- token.setRememberMe(true);
- try {
- user.login(token);
- String userID = (String) user.getPrincipal();
- LOGGER.info("User [" + userID + "] logged in successfully.");
- session.setAttribute("USERNAME", userID);
- return "success";
- } catch (UnknownAccountException uae) {
- errorMessage = "用户认证失败:" + "username wasn't in the system.";
- LOGGER.info(errorMessage);
- } catch (IncorrectCredentialsException ice) {
- errorMessage = "用户认证失败:" + "password didn't match.";
- LOGGER.info(errorMessage);
- } catch (LockedAccountException lae) {
- errorMessage = "用户认证失败:" + "account for that username is locked - can't login.";
- LOGGER.info(errorMessage);
- } catch (AuthenticationException e) {
- errorMessage = "登录失败错误信息:" + e;
- LOGGER.error(errorMessage);
- e.printStackTrace();
- token.clear();
- }
- session.setAttribute("ErrorMessage", errorMessage);
- return "error";
- }
- }
认证服务类
- @Service
- public class SystemAuthorizingRealm extends AuthorizingRealm {
- @Resource(name = "userService")
- private UserService userService;
- // 授权
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
- // TODO Auto-generated method stub
- return null;
- }
- // 认证
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
- UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
- Users user = userService.getUser(token.getUsername());
- if (user != null) {
- return new SimpleAuthenticationInfo(user.getName(), user.getPassword(), "");
- } else {
- return null;
- }
- }
- }
用户服务类
- @Service("userService")
- public class UserServiceImpl implements UserService {
- <span style="white-space:pre"> </span>@Autowired
- <span style="white-space:pre"> </span>private UserDao userDao;
- <span style="white-space:pre"> </span>public Users getUser(String userName) {
- <span style="white-space:pre"> </span>Users users = null;
- <span style="white-space:pre"> </span>try {
- <span style="white-space:pre"> </span>users = userDao.searchUser(userName);
- <span style="white-space:pre"> </span>} catch (DataAccessException e) {
- <span style="white-space:pre"> </span>e.printStackTrace();
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>return users;
- <span style="white-space:pre"> </span>}
- }
数据库操作类
- @Repository("UserDao")
- public class UserDaoImpl extends BaseDaoImpl implements UserDao {
- <span style="white-space:pre"> </span>
- <span style="white-space:pre"> </span>public Users searchUser(String userName) throws DataAccessException{
- <span style="white-space:pre"> </span>Users users = null;
- <span style="white-space:pre"> </span>try {
- <span style="white-space:pre"> </span>Session session = sessionFactory.openSession();
- <span style="white-space:pre"> </span>Query query = session.createQuery("from Users a where a.name=:name").setString(
- <span style="white-space:pre"> </span>"name", userName);
- <span style="white-space:pre"> </span>users = (Users) query.uniqueResult();
- <span style="white-space:pre"> </span>session.close();
- <span style="white-space:pre"> </span>} catch (Throwable e) {
- <span style="white-space:pre"> </span>throw new DataAccessException(e);
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>return users;
- <span style="white-space:pre"> </span>
- <span style="white-space:pre"> </span>}
- }
5. 内置表单过滤器
上面的程序是使用Spring的Web控制器来获取页面提交的数据,也可以使用Shiro内置的表单过滤器来实现页面数据提交。
修改applicationContext.xml增加过滤器
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <property name="securityManager" ref="securityManager" />
- <property name="loginUrl" value="/login.do" />
- <property name="successUrl" value="/main.do" />
- <property name="unauthorizedUrl" value="/error.do" />
- <property name="filters">
- <util:map>
- <entry key="authc">
- <bean class="com.peter.smallshow.security.CustomFormAuthenticationFilter">
- <property name="usernameParam" value="loginName" />
- <property name="passwordParam" value="password" />
- </bean>
- </entry>
- </util:map>
- </property>
- <property name="filterChainDefinitions">
- <value>
- /index.do = anon
- /login.do = authc
- /** = authc
- </value>
- </property>
- </bean>
表单中的参数固定写法是username、password、rememberMe。
可以通过<property name="usernameParam" value="loginName" />来设置
自定义的表单过滤类
自定义的表单过滤类
- @Service
- public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
- protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
- String username = getUsername(request);
- String password = getPassword(request);
- if (password == null) {
- password = "";
- }
- boolean rememberMe = false;
- String host = getHost(request);
- return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host);
- }
- }
6.工程代码
源码:smallShow-v0.9.1.rar
http://download.csdn.net/detail/peterwanghao/6858101
Web应用:smallShow.war 直接放到Tomcat下即可。
http://download.csdn.net/detail/peterwanghao/6858127
在本例子中使用Apache Shiro在Web应用中实现身份认证,将Shiro与spring进行集成,使用内嵌的derby数据库存储用户信息。
持久层为hibernate,数据库连接池为alibaba druid。
2. 准备
创建一个内嵌的derby数据库,本例使用的是db-derby-10.10.1.1。
2.1 建表
Create table users(
Id int primary key,
Name varchar(20),
Passwd varchar(20)
);
2.2 初始化数据
Insert into users values(1,’admin’,’admin’);
Insert into users values(2,’peter’,’peter’);
3. 配置
3.1 Web.xml
- <!-- Apache Shiro -->
- <filter>
- <filter-name>shiroFilter</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- <init-param>
- <param-name>targetFilterLifecycle</param-name>
- <param-value>true</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>shiroFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
3.2 ApplicationContext.xml
- <!-- 安全认证过滤器 -->
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <property name="securityManager" ref="securityManager" />
- <property name="loginUrl" value="/index.do" />
- <property name="filterChainDefinitions">
- <value>
- /login.do = anon
- /** = authc
- </value>
- </property>
- </bean>
- <!-- 定义 Shiro 主要业务对象 -->
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="systemAuthorizingRealm" />
- </bean>
- <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
- <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
4. 认证
登录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>Login</title>
- </head>
- <body>
- <form id="form1" name="form1" method="post" action="login.do">
- <p align="center">用户登录</p>
- <table width="296" border="1" align="center" bgcolor="#00FF99">
- <tr>
- <td width="98" height="34">用户名:</td>
- <td width="182"><label><input name="loginName"
- type="text" id="loginName" /> </label></td>
- </tr>
- <tr>
- <td height="36">密码:</td>
- <td><label> <input name="password" type="password"
- id="password" />
- </label></td>
- </tr>
- <tr>
- <td height="35" colspan="2"><label>
- <input type="submit" name="Submit" value="提交" />
- </label> <label> <input
- type="reset" name="Submit2" value="重置" />
- </label></td>
- </tr>
- </table>
- </form>
- </body>
- </html>
Web控制器
- @Controller
- public class LoginController {
- private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);
- @RequestMapping(value = "/login.do", method = RequestMethod.POST)
- public String isLogin(HttpServletRequest request, PasswordAuthcInfo passwordAuthcInfo) {
- String loginName = passwordAuthcInfo.getLoginName();
- String loginPassword = passwordAuthcInfo.getPassword();
- LOGGER.info("loginName:" + loginName + ";loginPassword:" + loginPassword);
- HttpSession session = request.getSession(true);
- String errorMessage = "";
- Subject user = SecurityUtils.getSubject();
- UsernamePasswordToken token = new UsernamePasswordToken(loginName, loginPassword);
- token.setRememberMe(true);
- try {
- user.login(token);
- String userID = (String) user.getPrincipal();
- LOGGER.info("User [" + userID + "] logged in successfully.");
- session.setAttribute("USERNAME", userID);
- return "success";
- } catch (UnknownAccountException uae) {
- errorMessage = "用户认证失败:" + "username wasn't in the system.";
- LOGGER.info(errorMessage);
- } catch (IncorrectCredentialsException ice) {
- errorMessage = "用户认证失败:" + "password didn't match.";
- LOGGER.info(errorMessage);
- } catch (LockedAccountException lae) {
- errorMessage = "用户认证失败:" + "account for that username is locked - can't login.";
- LOGGER.info(errorMessage);
- } catch (AuthenticationException e) {
- errorMessage = "登录失败错误信息:" + e;
- LOGGER.error(errorMessage);
- e.printStackTrace();
- token.clear();
- }
- session.setAttribute("ErrorMessage", errorMessage);
- return "error";
- }
- }
认证服务类
- @Service
- public class SystemAuthorizingRealm extends AuthorizingRealm {
- @Resource(name = "userService")
- private UserService userService;
- // 授权
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
- // TODO Auto-generated method stub
- return null;
- }
- // 认证
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
- UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
- Users user = userService.getUser(token.getUsername());
- if (user != null) {
- return new SimpleAuthenticationInfo(user.getName(), user.getPassword(), "");
- } else {
- return null;
- }
- }
- }
用户服务类
- @Service("userService")
- public class UserServiceImpl implements UserService {
- <span style="white-space:pre"> </span>@Autowired
- <span style="white-space:pre"> </span>private UserDao userDao;
- <span style="white-space:pre"> </span>public Users getUser(String userName) {
- <span style="white-space:pre"> </span>Users users = null;
- <span style="white-space:pre"> </span>try {
- <span style="white-space:pre"> </span>users = userDao.searchUser(userName);
- <span style="white-space:pre"> </span>} catch (DataAccessException e) {
- <span style="white-space:pre"> </span>e.printStackTrace();
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>return users;
- <span style="white-space:pre"> </span>}
- }
数据库操作类
- @Repository("UserDao")
- public class UserDaoImpl extends BaseDaoImpl implements UserDao {
- <span style="white-space:pre"> </span>
- <span style="white-space:pre"> </span>public Users searchUser(String userName) throws DataAccessException{
- <span style="white-space:pre"> </span>Users users = null;
- <span style="white-space:pre"> </span>try {
- <span style="white-space:pre"> </span>Session session = sessionFactory.openSession();
- <span style="white-space:pre"> </span>Query query = session.createQuery("from Users a where a.name=:name").setString(
- <span style="white-space:pre"> </span>"name", userName);
- <span style="white-space:pre"> </span>users = (Users) query.uniqueResult();
- <span style="white-space:pre"> </span>session.close();
- <span style="white-space:pre"> </span>} catch (Throwable e) {
- <span style="white-space:pre"> </span>throw new DataAccessException(e);
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>return users;
- <span style="white-space:pre"> </span>
- <span style="white-space:pre"> </span>}
- }
5. 内置表单过滤器
上面的程序是使用Spring的Web控制器来获取页面提交的数据,也可以使用Shiro内置的表单过滤器来实现页面数据提交。
修改applicationContext.xml增加过滤器
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <property name="securityManager" ref="securityManager" />
- <property name="loginUrl" value="/login.do" />
- <property name="successUrl" value="/main.do" />
- <property name="unauthorizedUrl" value="/error.do" />
- <property name="filters">
- <util:map>
- <entry key="authc">
- <bean class="com.peter.smallshow.security.CustomFormAuthenticationFilter">
- <property name="usernameParam" value="loginName" />
- <property name="passwordParam" value="password" />
- </bean>
- </entry>
- </util:map>
- </property>
- <property name="filterChainDefinitions">
- <value>
- /index.do = anon
- /login.do = authc
- /** = authc
- </value>
- </property>
- </bean>
表单中的参数固定写法是username、password、rememberMe。
可以通过<property name="usernameParam" value="loginName" />来设置
自定义的表单过滤类
自定义的表单过滤类
- @Service
- public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
- protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
- String username = getUsername(request);
- String password = getPassword(request);
- if (password == null) {
- password = "";
- }
- boolean rememberMe = false;
- String host = getHost(request);
- return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host);
- }
- }
6.工程代码
源码:smallShow-v0.9.1.rar
http://download.csdn.net/detail/peterwanghao/6858101
Web应用:smallShow.war 直接放到Tomcat下即可。
http://download.csdn.net/detail/peterwanghao/6858127