Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。下面主要讲述一下SpringMVC集成Shiro权限实现登录控制简单封装案例。
1.springmvc整合shiro权限,首先需要引入相关的jar包,maven项目中pom.xml文件,新增jar配置依赖,内容如下:
org.apache.shiro
shiro-core
1.2.4
org.apache.shiro
shiro-web
1.2.4
org.apache.shiro
shiro-quartz
1.2.4
org.apache.shiro
shiro-spring
1.2.4
org.apache.shiro
shiro-aspectj
1.2.4
2.新建AuthenticationFilter.java类文件,具体内容如下:package com.yoodb.core.shiro.filter;
import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
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.web.filter.PathMatchingFilter;
import org.apache.shiro.web.util.WebUtils;
public class AuthenticationFilter extends PathMatchingFilter{
private String failureUrl;
private String successUrl;
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
if (SecurityUtils.getSubject().isAuthenticated()) {
return true;
}
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
if (isLoginRequest(req)) {
if ("post".equalsIgnoreCase(req.getMethod())) {
boolean loginSuccess = login(req);
if (loginSuccess) {
redirectToSuccessUrl(req, resp);
}
}else {
saveRequestAndRedirectToLogin(req, resp);
}
}
return true;
}
private boolean redirectToSuccessUrl(HttpServletRequest req, HttpServletResponse resp) throws IOException {
WebUtils.redirectToSavedRequest(req, resp, successUrl);
return false;
}
private void saveRequestAndRedirectToLogin(HttpServletRequest req, HttpServletResponse resp) throws IOException {
WebUtils.saveRequest(req);
WebUtils.issueRedirect(req, resp, failureUrl);
}
private boolean login(HttpServletRequest req) {
String username = req.getParameter("username");
String password = req.getParameter("password");
try {
SecurityUtils.getSubject().login(new UsernamePasswordToken(username, password));
} catch (Exception e) {
req.setAttribute("shiroLoginFailure", e.getClass());
return false;
}
return true;
}
private boolean isLoginRequest(HttpServletRequest req) {
return pathsMatch(successUrl, WebUtils.getPathWithinApplication(req));
}
public String getFailureUrl() {
return failureUrl;
}
public void setFailureUrl(String failureUrl) {
this.failureUrl = failureUrl;
}
public String getSuccessUrl() {
return successUrl;
}
public void setSuccessUrl(String successUrl) {
this.successUrl = successUrl;
}
}
3.Realm充当Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。添加Realm类,新建UserRealm.java类文件,具体内容如下:package com.yoodb.core.shiro.realm;
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.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class UserRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(null);
authorizationInfo.setStringPermissions(null);
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// TODO Auto-generated method stub
UsernamePasswordToken upToken = (UsernamePasswordToken)token;
//获得用户名与密码
String username = upToken.getUsername();
// if(!"wang".equals(username)) {
// throw new UnknownAccountException(); //如果用户名错误
//}
String password = String.valueOf(upToken.getPassword());
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password .toCharArray(),getName());
return info;
}
}
4.Shiro的核心部分是SecurityManager,它负责安全认证与授权。Shiro本身已经实现了所有的细节,用户可以完全把它当做一个黑盒来使用。SecurityUtils对象,本质上就是一个工厂类似Spring中的ApplicationContext。Subject是初学者比较难于理解的对象,很多人以为它可以等同于User,其实不然。Subject中文翻译:项目,而正确的理解也恰恰如此。它是你目前所设计的需要通过Shiro保护的项目的一个抽象概念。通过令牌(token)与项目(subject)的登陆(login)关系,Shiro保证了项目整体的安全。
新建spring-shiro.xml文件,具体内容如下:<?xml version="1.0" encoding="UTF-8"?>
xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
/login = authc
/logout = logout
5.在spring相关的配置文件中,增加配置信息如下:
6.修改web.xml文件增加Shiro Filter过滤器配置,具体内容如下:
shiroFilter
org.springframework.web.filter.DelegatingFilterProxy
shiroFilter
/*
REQUEST