Shiro学习
JAVA SE 环境搭建Shiro框架
i. 导入shiro相关jar包
ii. 配置文件,存储临时文件
shiro.ini:存储数据、用户名、密码、角色、权限。一个角色可以有多个权限。
1. 获取安全管理器
Factory<SecurityManager> factory = new IniSecurityManagerFactory(“classpath:shiro.ini”);
SecurityManager securityManager = factory.getInstance();
2. 需要设置安全管理器
SecurityUtils.setSecurityManager(securityManager);
3. 获取Subject对象,即登录的用户
Subject currentUser= SecurityUtils.getSubject();
Session session = currentUser.getSession();
session.setAttribute(“name”,”王宁”);
String value =(String) session.getAttribute(“name”);
4. if(!currentUser.isAuthenticated()){
UserNamePasswordToken token = new UserNamePasswordToken(“root”,”123”);
token.setRemberMe(true);
try{
currentUser.login(token);
//没有出现任何异常,用户名和密码正确
}catch(UnknownAccountExeception e){
Log.info(“账户不存在”);
} catch(IncorrectCredentialsExeception e){
Log.info(“密码错误”);
} catch(LockedAccountExeception e){
Log.info(“用户已经锁死”);
}
}
currentUser.hasRole(“拥有指定角色”);
currentUser.isPermitted(“拥有制定权限”);
spring集成
1. Spring、Spring MVC的搭建
l 导入与框架相关的jar包
l web.xml中完成Spring文件的声明,(安装插件)
<!—Spring 声明-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!—配置一个上下文加载的监听器-->
<listener>
<listener-class>org.springframework.web.ContextLoaderListener</listener-class>
</listener>
<!--Spring MVC的声明-->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!—shiroFilter代理类
代理类会自动的到IOC容器中找在filter-name当中对应的对象
-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy </filter- class>
<init-param>
<param-name> targetFilterLifecyle </param-name>
<param-value> true </param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> shiroFilter </filter-name>
<url-pattern>/*<url-pattern>
<filter-mapping>
l 配置spring-mvc配置文件
<bean
class=”org.springframework.web.servlet.view.InternalResourceViewResoler”
>
<property name=”prefix” value=”/”></property>
<property name=”suffix” value=”.jsp”></property>
</bean>
<context:component-scan base-package=”*”></context:component-scan >
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:default-servlet-handler/>
l applicationContext.xml 配置spring
<!—安全管理bean
1.缓存技术:缓存管理.
2. realm :负责获取处理数据
-->
<bean id=”securityManager” class=”org.appache.shiro.web.mgt.DefaultWebSecirityManager”>
<property name=”cacheManager” ref=”cacheManager”>
<property name=”sessionMode” ref=”native”>
<property name=”realm” ref=”jdbcRealm”>
</bean>
<!—配置我们可以使用的缓存技术-->
<bean id=”cacheManager” class= “”></bean>
<!—配置shirofilter
1、shiroFilter这个bean的id必须与web.xml文件中的filter-name保持一致
-->
<bean id=”shiroFilter” class=”org.appache.shiro.spring.web.ShiroFilterFactoryBean”>
<property name=”securityManager” ref=”securityManager”>
<property name=”loginUrl” value=”/s/login.jsp”>
<property name=”successUrl” value=”/s/index.jsp”>
<property name = “unauthorizedUrl” value=”/s/unauthorized.jsp”>
<property name=”filterChainDefInitions”>
<value>
/logon.jsp = anon(匿名访问)
/** = authc (其他web资源通过认证才能访问)
<value>
</property>
</bean>
2. Shiro框架核心配置:spring的配置文件中配置的一个bean,org.appache.shiro.spring.web.ShiroFilterFactoryBean
3. Web.xml文件为什么还要配置一个DelegatingFilterProxy?
这是一个代理类,用来到Spring容器当中去找与filter-name相同的名字的bean实例。
4. URL匹配模式:
?:匹配一个字符
*:匹配零个或多个字符
**:匹配多个路径多个字符
URL 匹配顺序:采取第一次匹配优先的方式
1. Shiro认证的基本流程:
l Jsp,包含用户登录的信息,form表单当中
l SpringMVC控制器:处理用户的请求
获取用户的登录信息
shiro api 完成用户的登录验证
2. Shiro API 完成用户的认证
l 获取subject 类型的实例 Subject currentUser = SecurityUtils.getSubject();
l 判断用户是否已登录 currentUser.isAuthenticated()
l 使用UsernamePasswordToken对象封装用户名及密码
l 使用Subject实例中的login(token) currentUser.login(token)
l Realm:从数据库中获取安全数据
3. MD5加密
在Spring IOC的配置文件中,配置
<property name = “credentialsMatcher”>
<bean class=”org.appache.shiro.authc.credential.HashedCredentialMatcher”>
<property name=”hashAlgorithmName” value=”MD5”>
<property name=”hashIterations” value=”1024”>
</bean>
</property>
4. 盐值加载:在加密过程中添加特殊字符来确保加密结果不一致,比如添加主键。
Realm方法返回的对象调用下面这个构造
New SimpleAuthenticial(principal,sh,salt,realName);
Salt值为ByteSource salt = ByteSource.Util.bytes(userName);
5. 多realm 获取 数据
为什么要是用?将密码存入到多个数据库当中并且采取不同的加密算法。
第一种方式:
1. 书写多个Realm的实现类
2. SpringIOC容器中完成想用bean的设置
3. SecurityManager的bean中设置一个realms,并且通过集合对象完成属性的注入。
<bean id=”jdbcRealm” class=”com.shiro.bean.ShiroRealm”>
<property name=”credentialsMatcher”>
<bean class=”org.appache.shiro.authc.credential.hashedCredentialsMatcher”>
<property name=”hashAlgorithmName” value=”MD5”></property>
<property name=”hashIterations” value=”1024”></property>
</bean>
</property>
</bean>
<bean id=”secondRealm” class=”com.shiro.bean.SecondShiroRealm”>
<property name=”credentialsMatcher”>
<bean class=”org.appache.shiro.authc.credential.hashedCredentialsMatcher”>
<property name=”hashAlgorithmName” value=”SHA1”></property>
<property name=”hashIterations” value=”1024”></property>
</bean>
</property>
</bean>
6. 认证策略:shiro在进行认证,如何识别认证成功。
两个realm,前段用户输入的账号和密码需要与mysql和oracle比对。
1. 多个realm认证,有一个成功则成功。
2. 多个realm认证,全部成功才算成功。
7. <bean id=”authenticator” class=”org.apache.shiro.authc.pam.MoularRealmAuthenticator”>
<property name=”realms”>
<list>
<ref bean=”jdbcRealm”/>
<ref bean=”secondRealm”/>
</list>
</property>
<property name=” allSuccessfulStrategy” ref=” allSuccessfulStrategy”>
</bean>
<bean id=”allSuccessfulStrategy” class=”org.apache.shiro.authc.pam.AllSuccessfulStrategy”/>
<bean id=”atleastOneSuccessfulStrategy” class=”org.apache.shiro.authc.pam. AtleastOneSuccessfulStrategy”/>
8. 授权:也叫访问控制,在应用中控制谁访问哪些资源。
主体:在shiro应用中使用subject代表用户,用户只有授权以后才允许访问相应的资源。
权限:表示能不能访问某个资源。
角色:权限的集合。=
9. Shiro授权的三种方式
编程式:通过if/else授权代码块完成
注解式:在JAVA方法上添加相应的注释,没有权限将抛出相应的异常。
JSP标签:在前端通过相应的标签完成。
10. 可以通过IOC容器的配置文件完成指定web资源对应的角色 filterChainDefinition
web资源 = roles[角色
11. 一个用户进行登录,认证成功之后,最终还要查找认证成功的用户拥有什么样的角色。
Realm可以与数据库进行交互,获取指定认证成功的用户对应什么角色。
自定义一个Realm,继承AuthorizingRealm,完成认证和授权的角色。
IOC容器当中配置指定Realm的bean实例
告知securityManager使用哪一个授权管理器。
配置一个授权管理器。