Shiro框架学习笔记

一、概念

shiro是一个安全框架,主要可以帮助我们解决程序开发中认证和授权的问题。基于拦截器做的权限系统,权限控制的粒度有限,为了方便各种各样的常用的权限管理需求的实现,我们有必要使用比较好的安全框架,于是就出现了shiro安全框架,学习成本降低了很多,而且基本的功能也比较完善。

二、shiro提供的功能

1、Authentication:身份认证/登陆,验证用户是不是拥有相对应的身份;

2、Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者粒度的验证某个用户对某个资源是否具有权限;

3、Session Manager:会话管理,即用户登陆后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是Web环境的;

4、Cryptographt:加密,保护数据,如密码加密存储到数据库,而不是明文存储;

5、Web Support:Web支持,可以非常容易的继承到Web环境的;

6、Caching:缓存,比如用户登陆后,其用户信息、拥有的角色/权限不必每次去查,这样提高效率;

7、Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

8、Testing:提供测试支持;

9、Run As:允许一个用户假装另一个用户(如果我们允许)的身份进行访问;

10、Remember Me:记住我,这个是非常常见的功能,即一次登陆后,下次再来的话不用登陆了。

三、Shiro实现原理理解

也就是说对于我们而言,最简单的一个 Shiro 应用,通过 Subject 来进行认证和授权,而 Subject 又委托给 SecurityManager; 我们需要给 Shiro 的 SecurityManager 注入 Realm,从而SecurityManager 能得到合法的用户及其权限进行判断。

四、shiro的认证示例(Maven工程)

1.在pom.xml引入需要的jar包,可以去maven仓库官网复制

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hyt</groupId>
<artifactId>blog</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId><version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.0</version>
</dependency>
  <!-- 导入shiro和spring继承的jar包 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.2.3</version>
            </dependency>
            <!-- 导入shiro和web的jar包-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-web</artifactId>
                <version>1.2.3</version>
            </dependency>
</dependencies>
</project>

2.在web.xml中声明shiro拦截权限的过滤器

<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!--保证该过滤器的生命周期和spring 工厂中shiro过滤器对象的生命周期一致-->
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
<!--声明该过滤器代理工厂类中的id为什么的shiro过滤器对象-->
<init-param>
<param-name>targetBeanName</param-name>
<param-value>shiroFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

3.在spring的主配置文件汇总声明shiro的配置信息

<!--创建自定义域对象-->
<bean id="MyRealm" class="com.hyt.realm.MyRealm"></bean>
<!--创建shiro的安全管理器对象-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--要声明域,在域中读取认证和授权的数据-->
<property name="realm" ref="MyRealm"></property>
</bean>
<!--创建shiro的过滤器对象-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!--要注入安全管理器对象-->
<property name="securityManager" ref="securityManager"></property>
<!--配置登录请求的路径-->
<property name="loginUrl" value="/user/login.do"></property>
<!--配置shiro认证和授权的过滤器-->
<property name="filterChainDefinitions">
<value>
<!--对静态资源不拦截-->
<!--anon指匿名访问的过滤器,所有匿名用户都可以访问static下面的资源-->
/login.jsp=anon
<!--authc指必须经过认证(登录过之后)才能访问的请求 /*代表所有有一个斜杠的请求都要经过认证 -->
/admin/**=authc
</value>
</property></bean>
</beans>

4.创建自定义域对象MyRealm

package com.hyt.realm;

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.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import com.hyt.entity.Blogger;
import com.hyt.service.BloggerService;
import com.hyt.util.Const;

public class MyRealm extends AuthorizingRealm {
	@Resource
	private BloggerService bloggerService;
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		
		String userName=(String)token.getPrincipal();
		Blogger blogger=bloggerService.getByUserName(userName);
		if(blogger!=null) {
			SecurityUtils.getSubject().getSession().setAttribute(Const.CURRENT_USER, blogger);
			AuthenticationInfo authenInfo=new SimpleAuthenticationInfo(blogger.getUserName(), blogger.getPassword(),getName());
			return authenInfo;
		}
		return null;
	}

}

5.在控制器(Controller)中使用shiro去做登陆认证

package com.hyt.controller;

import javax.servlet.http.HttpServletRequest;    
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.hyt.entity.Blogger;
import com.hyt.util.CryptographyUtil;
/**
 * 博主登录相关
 *
 */
@Controller
@RequestMapping("/blogger")
public class BloggerController {
	@RequestMapping("/login")
	public String login(Blogger blogger,HttpServletRequest request) {
		String userName=blogger.getUserName();
		String password=blogger.getPassword();
		String pw=CryptographyUtil.md5(password,"amos");
		
		Subject subject=SecurityUtils.getSubject();
		UsernamePasswordToken token=new UsernamePasswordToken(userName,pw);
		
		try {
			//传递token给shiro的realm
			subject.login(token);
			return "redirect:/admin/main.jsp";
		} catch (Exception e) {
			e.printStackTrace();
			request.setAttribute("blogger", blogger);
			request.setAttribute("errorInfo", "用户名或密码错误!");
		}
		//return "redirect:../login.jsp";
		return "login";
	}
	
}

6.采用MD5加密,以下是MD5加密工具类(给md5加点“盐”,加密型更高)

package com.hyt.util;

import org.apache.shiro.crypto.hash.Md5Hash;

public class CryptographyUtil {
	
	public static String md5(String str,String salt) {
		return new Md5Hash(str,salt).toString();
	}

	public static void main(String[] args) {
		System.out.println(md5("991109","amos"));

	}

}

密码加密存储之后,使用shiro做校验时,应该在realm中做如下配置:

<!--创建自定义域对象-->
<bean id="MyRealm" class="com.hyt.realm.MyRealm">
    <property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>
<!-- 创建凭证匹配器对象-->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
    <!--指定要对用户传过来的明文的密码最什么加密-->
    <property name="hashAlgorithmName" value="md5"></property>
    <!--指明hash迭代的次数-->
    <property name="hashIterations" value="10"></property>
</bean>

以上代码内容提取于最近在写的SSM框架下的个人博客项目。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值