您的位置:首页 > 编程语言 > Java开发

Shiro在strust2+spring中的应用

2016-01-27 00:26 399 查看
  Shiro 是一个用 Java 语言实现的框架,通过一个简单易用的 API 提供身份验证和授权。使用 Shiro,您就能够为您的应用程序提供安全性而又无需从头编写所有代码。

  由于最近学习用到shiro,分享一下自己使用和剖析的经过。

  首先是shiro的核心功能



  shiro的基本调用调用关系



  步骤如下:

1.首先设置web.xml文件引入shiro的过滤器

shiroFilterorg.springframework.web.filter.DelegatingFilterProxytargetFilterLifecycletrueOpenSessionInViewFilter/*shiroFilter/*struts2/*


2.在spring中引入shiro的相关核心类

<?xml version="1.0" encoding="UTF-8"?>
Shiro安全配置
/index.jsp* = anon
/home* = anon
/sysadmin/login/login.jsp* = anon
/sysadmin/login/logout.jsp* = anon
/login* = anon
/logout* = anon
/staticfile/** = anon

/** = authc

3.编写自己的Realm实现类,需继承AuthorizingRealm。当shiro认证和授权时候回调

package cn.tarena.ht.shiro;

import java.util.List;

import org.apache.log4j.Logger;
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.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;

import cn.tarena.ht.domain.User;
import cn.tarena.ht.service.UserService;

public class AuthRealm extends AuthorizingRealm{
private static Logger log = Logger.getLogger(AuthRealm.class);
//spring框架注入,将shiro和spring整合。
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}

//授权 此方法每遇到shiro标签或者注解都会执行一次
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
log.info("授权");

//从principals中获取第一个元素,它就是当前用户对象
User _user = (User)principals.fromRealm(getName()).iterator().next();
String username = _user.getUsername();
//获取到所有角色权限的字符串,采用缓存可以大幅度减少查询次数
List permissionList = userService.getModuleByUsername(username);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(permissionList);	//将权限串集合,内部进行比较

return info;
}

//认证(登录)
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
log.info("认证");
//获取spring容器中的bean
UsernamePasswordToken uToken = (UsernamePasswordToken)token;
User _user = userService.findByUsername(uToken.getUsername());	//持久化
AuthenticationInfo info = null;
if(_user!=null){
//参数:数据库的用户,数据库中的密码(加密后),当前的自定义realm
info = new SimpleAuthenticationInfo(_user,_user.getPassword(),getName());
}

return info;
}

}


4.如果需要自己制定加密方法要继承SimpleCredentialsMatcher并把实现类注入给shiro,见spring配置文件

package cn.tarena.ht.shiro;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;

public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken usertoken = (UsernamePasswordToken) token;

//注意token.getPassword()拿到的是一个char[],不能直接用toString(),它底层实现不是我们想的直接字符串,只能强转
String salt = usertoken.getUsername();
Object tokenCredentials =md5(String.valueOf(usertoken.getPassword()),salt);
Object accountCredentials = getCredentials(info);

//将密码加密与系统加密后的密码校验,内容一致就返回true,不一致就返回false
return equals(tokenCredentials, accountCredentials);
}

//高强度加密算法,不可逆 salt=username+id
public String md5(String password, String salt){
return new Md5Hash(password,"zs"+salt,2).toString();
}
}


shiro的登入认证:

public String login(){
if(userName==null||password==null)
return "login";

AuthenticationToken token=new UsernamePasswordToken(userName,password);
SecurityUtils.setSecurityManager(securityManager);
Subject sub=SecurityUtils.getSubject();

try{
sub.login(token);
User _user=(User)sub.getPrincipal();
System.out.println(_user.getDept().getDeptName());//防止跳转造成懒加载问题
session.put(SysConstant.CURRENT_USER_INFO, _user);	//记录session
return SUCCESS;
}catch(Exception e){
String msg = "登录错误,请重新填写用户名密码!";
this.setErrorInfo(msg);
return "login";
}


shiro网站中的权限菜单控制:

货运管理

统计分析

基础信息


shiro方法中的权限控制:
@RequiresPermissions("系统管理")
public String list(){
List dataList = deptService.find("from Dept o", Dept.class, null);
super.put("dataList", dataList);

return "plist";
}


以上是基本shiro功能的使用,附上授权和认证的流程图:





  shiro的教科书式网站:http://www.ibm.com/developerworks/cn/web/wa-apacheshiro/ 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring ssh shiro