shiro再次学习
来源:互联网 发布:模式识别 算法 编辑:程序博客网 时间:2024/05/16 14:15
编辑器要配置好spring的插件。具体可以百度
首先配置spring的环境
web.xml下
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
此处是spring的配置
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
此处是springmvc的配置
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
此处是shiro的配置 !此处要等spring配置好之后再加入!
创建
applicationContext.xml 创建在src根目录下
用于做spring的配置
创建spring-servlet.xml 创建在web-inf下
<context:component-scan base-package="com.test.shiro"></context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:default-servlet-handler/>
这里是做springmvc用的 前端控制器 扫描的包
新建这个路径
com.test.shiro
新建jsp文件 user.jsp
运行项目:http://localhost:8080/shiro/user.jsp
打开出现user.jsp正常说明SPRING的环境已经配置好了
------
------
接下来开始整合shiro
web.xml文件已经加入了
在applicationContex.xml(也就是SPING来管理的shiro)中写入
核心部分 权限管理 SecurityManager
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/> 缓存
------ 这里是整合后才需要的 先注释 不然报错
<property name="authenticator" ref="authenticator"></property> <property name="realms"> <list> <ref bean="jdbcRealm"/> <ref bean="secondRealm"/> </list> </property> <property name="rememberMeManager.cookie.maxAge" value="10"></property>
------ 这里是整合后才需要的 先注释 不然报错
现在需要的配置是 :全部整合好了之后可以不用 <property name="realm" ref="jdbcRealm"></property>
</bean>
1.配置缓存cacheManager
cacheManager采用企业的管理方式 使用ehcache 。这个是需要加入jar包的 还有一种直接引用ehcachemanager
然后配置XML文件后期才再给。直接拿来使用就行。
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- Set a net.sf.ehcache.CacheManager instance here if you already have one. If not, a new one
will be creaed with a default config:
<property name="cacheManager" ref="ehCacheManager"/> -->
<!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance to inject, but you want
a specific Ehcache configuration to be used, specify that here. If you don't, a default
will be used.: -->
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean>
2.可以配置session 现在展示不用
3.实现realm
用接口的方式实现
<bean id="jdbcRealm" class="com.test.shiro.realms.ShiroRealm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"></property>
<property name="hashIterations" value="1024"></property>
</bean>
</property>
</bean>
java文件:
4.配置生命周期shiro
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
5.ioc容器可以使用shiro的注解(配置了4之后才会出现效果)
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
6.配置shirofiter 这里和web.xml中是是对应的。
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.jsp"/>
<property name="successUrl" value="/list.jsp"/>
<property name="unauthorizedUrl" value="/unauthorized.jsp"/>
------ 这里是整合后才需要的 先注释 不然报错
<property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property> 后期加上比较好的配置
------ 这里是整合后才需要的 先注释 不然报错
<!-- 配置哪些页面需要受保护. 以及访问这些页面需要的权限.
1). anon 可以被匿名访问
2). authc 必须认证(即登录)后才可能访问的页面.
3). logout 登出.
4). roles 角色过滤器 -->
<property name="filterChainDefinitions">
<value> /login.jsp = anon
/shiro/login = anon
/shiro/logout = logout
/user.jsp = roles[user]
/admin.jsp = roles[admin]
# everything else requires authentication:
/** = authc </value> </property>
</bean>
-----运行。此时框架已经可以跑起来 下载地址:http://download.csdn.net/detail/u013354696/9864885
下面进行整合realm实现认证
/shiro/src/com/test/shiro/handler/ShiroHandler.java 新建控制器
大致的作用就是将表单接收到的用户密码封装起来。进行登录验证
记得要加上控制器的注解
@Controller@RequestMapping("/shiro")public class ShiroHandler {@RequestMapping("/login")public String login(@RequestParam("username") String username,@RequestParam("password") String password) {Subject subject = SecurityUtils.getSubject();if (!subject.isAuthenticated()) {UsernamePasswordToken token = new UsernamePasswordToken(username,password);token.setRememberMe(true);try {subject.login(token);} catch (AuthenticationException e) {System.out.println("登录失败" + e.getMessage());}}return "redirect:/list.jsp";}}
/shiro/src/com/test/shiro/realms/ShiroRealm.java 这个继承类之前就已经创建好。但是不用实现realm接口要改为继承AuthenticatingRealm
public class ShiroRealm extends AuthenticatingRealm {@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("doGetAuthenticationInfo"+token);return null;}}
到此,可以运行项目会发现地址栏目的改变:
http://localhost:8080/shiro/login.jsp;jsessionid=BB3ACC73995EC9EE6AFB0FEC74DAC2D1
后面读了一个jsessionid的参数
输入了登录密码信息后,控制台会打印出
doGetAuthenticationInfo:org.apache.shiro.authc.UsernamePasswordToken - 456, rememberMe=true
登录失败Realm [com.test.shiro.realms.ShiroRealm@7c1e7] was unable to find account data for the submitted AuthenticationToken [org.apache.shiro.authc.UsernamePasswordToken - 456, rememberMe=true].
证明执行成功
接下来在次改写/shiro/src/com/test/shiro/realms/ShiroRealm.java
@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 1将AuthenticationToken转为usernamepasswordtokenUsernamePasswordToken upToken = (UsernamePasswordToken) token;// 2获取usernamepasswordtoken 中的usernameString username = upToken.getUsername();// 3从数据库查询username的记录if ("unknown".equals(username)) {throw new UnknownAccountException("用户不存在");}//用户 密码 当前realm 直接用getName()SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,"123456", getName());return info;}
其实就是做认证。用户名没有限定。密码123456 成功等会会进入跳转页面list.jsp
当然 也可以用AuthenticationToken 直接token.getPrincipal();强转一下获取当前用户信息这样就不需要 UsernamePasswordToken
开启加密MD5算法
web.xml里面的realm 改成这样
<bean id="jdbcRealm" class="com.test.shiro.realms.ShiroRealm"> <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="MD5"></property> <property name="hashIterations" value="1024"></property> </bean> </property> </bean>
public static void main(String[] args) {Object re =new SimpleHash("MD5","123456" , null,1024);System.out.println(re);}
生成一个用MD5加密1024次 没有盐值的123456密码。
然后在替换到SimpleAuthenticationInfo 中的密码。就相当于这里已经执行了加密的算法
这里是最简单的实现
接下来是完整版本的实现
@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 1将AuthenticationToken转为usernamepasswordtokenUsernamePasswordToken upToken = (UsernamePasswordToken) token;// // 2获取usernamepasswordtoken 中的usernameString username = upToken.getUsername();String mima = null;// String username = (String) token.getPrincipal();System.out.println("登录用户:" + username);// 3从数据库查询username的记录if ("unknown".equals(username)) {throw new UnknownAccountException("用户不存在");}if ("admin".equals(username)) {mima = "038bdaf98f2037b31f1e75b5b4c9b26e";} else if ("user".equals(username)) {mima = "098d2c478e9c11555ce2823231e02ec1";}ByteSource yan = ByteSource.Util.bytes(username);// 用户 密码 盐值 当前realm 直接用getName()SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,mima, yan, getName());return info;}
----
以上完成了基本的加密和认证 还没有接入数据库的服务。全部都是静态的数据
----
接下来进行多realm的认证
场景的认证: 多个数据库源进行认证。需要多个realm实现不同的认证策略,比如密码的加密方式SHA1, MD5加密
/shiro/src/com/test/shiro/realms/SencondRealm.java
@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 1将AuthenticationToken转为usernamepasswordtokenUsernamePasswordToken upToken = (UsernamePasswordToken) token;// // 2获取usernamepasswordtoken 中的usernameString username = upToken.getUsername();String mima = null;// String username = (String) token.getPrincipal();System.out.println("登录用户:" + username);// 3从数据库查询username的记录if ("unknown".equals(username)) {throw new UnknownAccountException("用户不存在");}if ("admin".equals(username)) {mima = "ce2f6417c7e1d32c1d81a797ee0b499f87c5de06";} else if ("user".equals(username)) {mima = "073d4c3ae812935f23cb3f2a71943f49e082a718";}ByteSource yan = ByteSource.Util.bytes(username);// 用户 密码 盐值 当前realm 直接用getName()SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,mima, yan, getName());return info;}public static void main(String[] args) {Object re = new SimpleHash("SHA1", "123456",ByteSource.Util.bytes("user"), 1024);System.out.println(re);}
两个realm几乎是一样的,
在spring中配置realm
/shiro/src/applicationContext.xml加入
<bean id="secondRealm" class="com.test.shiro.realms.SencondRealm"> <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="SHA1"></property> <property name="hashIterations" value="1024"></property> </bean> </property> </bean>
securityManager中的
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="cacheManager" ref="cacheManager"/> <property name="authenticator" ref="authenticator"></property> <property name="realms"> <list> <ref bean="jdbcRealm"/> <ref bean="secondRealm"/> </list> </property> <!-- <property name="rememberMeManager.cookie.maxAge" value="10"></property> --> </bean>
改为这个样子实现多realm
在配置一个认证器 具体可以去百度认证器策略。这里是所有的realm都认证
<bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator"> <property name="authenticationStrategy"> <bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean> </property> </bean>
也可以这样写 具体的策略可以自己决定
<bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator"> <!-- <property name="authenticationStrategy"> <bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean> </property> --> <property name="realms"> <list> <ref bean="jdbcRealm"/> <ref bean="secondRealm"/> </list> </property> <property name="authenticationStrategy"> <bean class="org.apache.shiro.authc.pam.AllSuccessfulStrategy"></bean> </property> </bean>
项目跑起来可以自己进行测试了
刚刚以上是登录方面的,现在到配置权限
/shiro/src/com/test/shiro/realms/ShiroRealm.java 中的继承类改为 AuthorizingRealm 在实现方法
doGetAuthorizationInfo方法就是实现授权的方法
@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection Principals) {//1. 从PrincipalCollection 拿到用户的信息Object username = Principals.getPrimaryPrincipal();//2. 拿到登录信息,去获取角色(查询数据库)Set<String> roles =new HashSet<>();roles.add("user");if("admin".equals(username)){roles.add("admin");}//3.都要实现这个接口返回值SimpleAuthorizationInfo info =new SimpleAuthorizationInfo(roles);return info;}
完成页面
实现注解: 如果出错。权限限制都失效。把这个放到spring-mvc.xml中
<beanclass="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"depends-on="lifecycleBeanPostProcessor"><property name="proxyTargetClass" value="true" /></bean><beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager" /></bean>
进行测试。可以发现admin才可以获取到时间
-------
接下来可以将配置权限提取出来
appxxxx.xml
<bean id="filterChainDefinitionMap" factory-bean="filterChainDefinitionMapBuilder" factory-method="buildFilterChainDefinitionMap"></bean> <bean id="filterChainDefinitionMapBuilder" class="com.test.shiro.factory.FilterChainDefinitionMapBuilder"></bean>
shiroFilter中加入
<property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property>
创建一个class
/shiro/src/com/test/shiro/factory/FilterChainDefinitionMapBuilder.java
public LinkedHashMap<String, String> buildFilterChainDefinitionMap() {LinkedHashMap<String, String> map =new LinkedHashMap<>();map.put("/login.jsp", "anon");map.put("/shiro/login", "anon");map.put("/shiro/logout", "logout");map.put("/user.jsp", "authc,roles[user]");map.put("/admin.jsp", "authc,roles[admin]");map.put("/list.jsp", "user");map.put("/**", "authc");return map;
- shiro再次学习
- shiro学习
- Shiro学习
- shiro学习
- shiro学习
- shiro学习
- shiro 学习
- shiro 学习
- shiro学习
- Shiro 学习
- shiro学习
- 【shiro】shiro学习笔记1-shiro初识
- shiro学习-shiro集成cas
- shiro学习:shiro实现授权
- 再次学习C++
- 【学习】再次发奋
- 再次学习struts1
- 再次学习C++string
- 网上看到的收藏了
- Bootstrapt03栅格系统
- linux命令大全
- 进程隐藏与进程保护(SSDT Hook 实现)(二)
- 控制台程序求解有理式(带括号,适用于int类型)
- shiro再次学习
- 安卓广播升级 RxBus的实现及简单使用
- HDU 2001
- vs2015的asp.net项目用vs2010打开
- TBS腾讯浏览服务的SDK接入-Android studio
- 百度地图2.0离线版的制作
- deep-learning 笔记
- OpenGL-ArrayIndexOutOfBoundsException: remaining() < count < needed
- 线程等待执行完毕