1.下载shiro
http://shiro.apache.org/download.html
2.shiro架构的核心内容介绍
①Subject_:_应用代码直接交互的对象是Subject,****与****Subject 的所有交互都会委托给 SecurityManager;
②SecurityManager****:**安全管理器;****即所有与安全有关的操作都会与******SecurityManager**** 交互;且其管理着所有Subject
③Realm****:****Shiro 从 ****Realm 获取安全数据(如用户、角色、权限),****就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色/权限进行验证用户是否能进行操作.
3.引入shiro依赖
1.2.3
net.sf.ehcache
ehcache-core
2.6.6
org.apache.shiro
shiro-ehcache
${shiro.version}
org.apache.shiro
shiro-core
${shiro.version}
org.apache.shiro
shiro-web
${shiro.version}
org.apache.shiro
shiro-spring
${shiro.version}
4.首先在web.xml中加入shiro过滤器
shiroFilter
org.springframework.web.filter.DelegatingFilterProxy
targetFilterLifecycle
true
shiroFilter
/*
REQUEST
FORWARD
ERROR
INCLUDE
5.添加shiro与spring集成的配置文件application-shiro.xml
/**/*login*/**=anon
/resources/**=anon
/**/*logout*/**=logout
/**=user
6.缓存管理器ehcache.xml
????
7.自定义realm
package com.plat.shiro;
import javax.annotation.Resource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.session.Session;
import com.plat.commons.model.SysUser;
import com.plat.service.SysUserService;
public class CustomJdbcRealm extends JdbcRealm {
@Resource
private SysUserService sysUserService;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("------doGetAuthenticationInfo-------");
/**
* js --> sysUser/login --> Subject.login(UsernamepasswordToken) --> CustomJdbcRealm
*/
UsernamePasswordToken usernamePasswordToken =(UsernamePasswordToken) token;
//获取登录账号
String account=usernamePasswordToken.getUsername();
SysUser sysUser=sysUserService.findByAccount(account);
if(sysUser==null) {
throw new UnknownAccountException();
}
//判断用户名和密码是否正确
if(!sysUser.getPassword().equals(new String (usernamePasswordToken.getPassword()))) {
throw new IncorrectCredentialsException();
}
//判断用户是否被禁用
if(sysUser.getIsUse()==0) {
throw new LockedAccountException();
}
//用户登录成功,将用户保存到session中
Session session= SecurityUtils.getSubject().getSession();
session.setAttribute("sysUser", sysUser);
//参数1:Subject.getPrincipal()获取到的就是参数一传入的内容
//参数2:shiro进行用户信息比对的时候使用的密码
//参数3:realm名称,getName方法自动生成一个realm的名称
return new SimpleAuthenticationInfo(account,sysUser.getPassword(),getName());
}
}
8.登录方法
@RequestMapping("/login")
@ResponseBody
public String login(String account,String password) {
//返回信息
String message = "";
if(!isNotNull(account)) {
message="登录账号不能为空";
}
if(message=="" && !isNotNull(password)) {
message="登录密码不能为空";
}
//登录
if(!isNotNull(message)) {
Subject currentUser=SecurityUtils.getSubject();
//加密密码
String md5Password = DigestUtil.hmacSign(password, DigestUtil.digest("heheda"));
UsernamePasswordToken upToken=
new UsernamePasswordToken(account,md5Password);
//记住我
//upToken.setRememberMe(true);
try {
//进入shiro的登录,此时将进入自定义的realm中进行安全验证
currentUser.login(upToken);
message="success";
}catch (UnknownAccountException uae) {
message="账号不存在";
}catch (IncorrectCredentialsException ice) {
message="用户名或者密码错误";
}catch (LockedAccountException lae) {
message="账号已被锁定";
} catch (AuthenticationException e) {
message="登录异常,请稍后再试!!";
e.printStackTrace();
}
}
return message;
}
9.MD5
package com.plat.commons.util;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class DigestUtil {
private static String encodingCharset = "UTF-8";
/**
* @param aValue
* @param aKey
* @return
*/
public static String hmacSign(String aValue, String aKey) {
byte k_ipad[] = new byte[64];
byte k_opad[] = new byte[64];
byte keyb[];
byte value[];
try {
keyb = aKey.getBytes(encodingCharset);
value = aValue.getBytes(encodingCharset);
} catch (UnsupportedEncodingException e) {
keyb = aKey.getBytes();
value = aValue.getBytes();
}
Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
for (int i = 0; i < keyb.length; i++) {
k_ipad[i] = (byte) (keyb[i] ^ 0x36);
k_opad[i] = (byte) (keyb[i] ^ 0x5c);
}
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
return null;
}
md.update(k_ipad);
md.update(value);
byte dg[] = md.digest();
md.reset();
md.update(k_opad);
md.update(dg, 0, 16);
dg = md.digest();
return toHex(dg);
}
public static String toHex(byte input[]) {
if (input == null)
return null;
StringBuffer output = new StringBuffer(input.length * 2);
for (int i = 0; i < input.length; i++) {
int current = input[i] & 0xff;
if (current < 16)
output.append("0");
output.append(Integer.toString(current, 16));
}
return output.toString();
}
/**
*
* @param args
* @param key
* @return
*/
public static String getHmac(String[] args, String key) {
if (args == null || args.length == 0) {
return (null);
}
StringBuffer str = new StringBuffer();
for (int i = 0; i < args.length; i++) {
str.append(args[i]);
}
return (hmacSign(str.toString(), key));
}
/**
* @param aValue
* @return
*/
public static String digest(String aValue) {
aValue = aValue.trim();
byte value[];
try {
value = aValue.getBytes(encodingCharset);
} catch (UnsupportedEncodingException e) {
value = aValue.getBytes();
}
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
return toHex(md.digest(value));
}
public static void main(String[] args) {
// 参数1: 明文(要加密的数据) 参数2: 密钥
System.out.println(DigestUtil.hmacSign("11111", "dddd"));
}
}