Spring集成Shiro HelloWorld之初步实现登陆及验证
来源:互联网 发布:星际淘宝网笔下 编辑:程序博客网 时间:2024/05/21 18:41
- 加入相关jar包
- 在webxml中进行相关配置
- 配置Spring的Listener
- 配置由Spring委托接管Shiro的Filter
- 配置SpringMVC的DispatcherServlet
- 配置Spring的applicationContextxml文件
- 配置SpringMVC的springDispatcherServlet-servletxml
- 编写SpringMVC处理请求的Handler类
今天抽空复习了一下Shiro这个权限框架与Spring的集成, 顺便写了个HelloWorld例子, 作为个人笔记记录同时也提供给需要的朋友参考.
加入相关jar包
加入相关jar包 见脚注: 1
Shiro版本: shiro-root-1.2.2-source-release
Spring版本: spring-framework-4.0.0.RELEASE-dist
在web.xml中进行相关配置
配置Spring的Listener
<!-- needed for ContextLoaderListener --><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委托接管Shiro的Filter
Filter配置可以从Shiro的源码中下的shiro-root-1.2.2-source-release\shiro-root-1.2.2\samples\spring\src\main\webapp\WEB-INF
下的web.xml
中找到.
<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>
配置SpringMVC的DispatcherServlet
<!-- The front controller of this Spring Web application 这个Spring WEB应用的前端控制器, responsible for handling all application requests 负责处理所有应用请求. --> <!-- 配置SpringMVC的DispatcherServlet --> <servlet> <servlet-name>springDispatcherServlet</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 将所有请求映射给DispatcherServlet以便处理. --> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
配置Spring的applicationContext.xml文件
从shiro-root-1.2.2-source-release\shiro-root-1.2.2\samples\spring\src\main\webapp\WEB-INF下的applicationContext.xml找到相关配置.
配置SecurityManager
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="cacheManager" ref="cacheManager"/> <!-- 配置自定义的Realm --> <property name="realm" ref="realm"/> </bean>
配置securityManager中引用的CacheManager和自定义的Realm, cacheManager和realm要配置在securityManager的代码上方.
配置自定义的Realm, 来让上面的SecurityManager引用管理
<bean id="realm" class="com.al0n4k.shiro.helloworld.reaml.MyRealm"></bean>
我们需要新建一个类来继承类实现其中的授权和验证方法
package com.al0n4k.shiro.helloworld.reaml;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.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;/** * @author AL0n4k * AuthorizingRealm继承自AuthencatingRealm类. */public class MyRealm extends AuthorizingRealm{ /** * 该方法继承自 AuthorizingRealm抽象类(用于授权的Realm) */ @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { return null; } /** * 该方法继承自 AuthencatingRealm抽象类(用于认证的Realm) */ @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token1) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) token1; /**从token中获取username, 然后根据username从数据中读取指定的密码. * 之后使用从数据库中查询出的账号密码信息创建SimpleAuthenticationInfo, * 然后将这个对象返回时, shiro内部会帮我们跟token中username和password进行对比判断是否成功登陆! 参考Shiro方法实现: org.apache.shiro.authc.credential.SimpleCredentialsMatcher.doCredentialsMatch(AuthenticationToken, AuthenticationInfo) 具体到底层比较的算法是: // 将token中的密码和Credentials中的密码转成byte数组进行比较 public static boolean equals(byte[] a, byte[] a2) { 先比较引用值, 如果内存引用值一样, 返回true if (a==a2) return true; 如果其中一个为null返回false if (a==null || a2==null) return false; // 否则获取两个的长度进行对比, 如果长度不一样, 返回false. int length = a.length; if (a2.length != length) return false; // 否则长度一样的话, 就比较每一个字符是否一样. for (int i=0; i<length; i++) if (a[i] != a2[i]) return false; return true;} * */ String username = token.getUsername(); // 模拟查询数据库 System.out.println("从数据中根据用户名查询密码"); /** * 如果从数据库中找不到用户名, 那么直接返回null. * 否则就创建SimpleAuthenticationInfo对象来将从数据库中读取到的账号密码封装为pricipal(当前登录负责人)和credentials(凭证) * 但我们这里因为是简单的helloworld就默认将请求中的username和password设置到这个对象的构造器参数中. * 如果返回null, 那么shiro框架则认为从token中根据username找不到对应的账号,参见Shiro实现方法: org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(Realm, AuthenticationToken) Object principal = username; Object credentials = "1234"; String realmName = getName(); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, realmName); return info; }}
配置缓存
<!-- 配置缓存. --><bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:ehcache.xml" /></bean>
配置Spring提供的可以自动调用Shiro对象的init()和destroy()方法的beanProcessor
<!-- 配置可以自动调用Shiro对象的init()和destroy()方法 --><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /><!-- Enable Shiro Annotations for Spring-configured beans. Only run after the lifecycleBeanProcessor has run:开启Shiro的注解在Spring已经配置的bean对象上, 但需要在LifecycleBeanPostProcessor这个bean已经配置的情况下才可以运行--><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>
配置ShiroFilter
<!-- 配置Shiro的Filter, 来拦截资源的请求. --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <!-- 配置登陆页面 --> <property name="loginUrl" value="login.jsp" /> <!-- 配置未授权的页面 --> <property name="unauthorizedUrl" value="unauthorized.jsp" /> <!-- 配置过滤器链定义 格式: 资源地址 = 访问的需要的权限 --> <property name="filterChainDefinitions"> <value> /favicon.ico = anon /logo.png = anon /shiro.css = anon /s/login = anon # allow WebStart to pull the jars for the swing app: /*.jar = anon # everything else requires authentication: /** = authc </value> </property></bean>
ShiroFilter的过滤书写格式
配置SpringMVC的springDispatcherServlet-servlet.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 配置需要让SpringMVC自动扫描的包 --> <context:component-scan base-package="com.al0n4k.shiro.helloworld.reaml"></context:component-scan> <!-- 配置Spring提供的内部视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> <!-- 配置SpringMVC的注解驱动 --> <mvc:annotation-driven></mvc:annotation-driven> <!-- 配置默认的Servlet处理器 Configures a handler for serving static resources by forwarding to the Servlet container's default Servlet. Use of this handler allows using a "/" mapping with the DispatcherServlet while still utilizing the Servlet container to serve static resources. This handler will forward all requests to the default Servlet. Therefore it is important that it remains last in the order of all other URL HandlerMappings. That will be the case if you use the "annotation-driven" element or alternatively if you are setting up your customized HandlerMapping instance be sure to set its "order" property to a value lower than that of the DefaultServletHttpRequestHandler, which is Integer.MAX_VALUE. --> <mvc:default-servlet-handler/></beans>
编写SpringMVC处理请求的Handler类
package com.al0n4k.shiro.helloworld.handler;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.mgt.SubjectFactory;import org.apache.shiro.subject.Subject;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;/** * @author AL0n4k */@Controllerpublic class ShiroHandler { @RequestMapping( "/login" ) public String login(@RequestParam( "username" ) String username, @RequestParam( "password" ) String password) { Subject currentUser = SecurityUtils.getSubject(); Class<? extends Subject> class1 = currentUser.getClass(); System.out.println(class1); if (!currentUser.isAuthenticated()) { UsernamePasswordToken token = new UsernamePasswordToken(username, password); //token.setRememberMe(true); try { // login方法会帮我们判断账号是否为空, 如果为空则抛出IllegalStateException异常. currentUser.login(token); } catch ( AuthenticationException e ) { // 该异常是指验证token是否为null时 token为null. System.out.println("验证账号密码时不匹配, 登陆失败!"); return "forward:/failure.jsp"; } } return "success"; }}
- 一般直接把shiro自带和spring下required文件夹中的jar包都加入即可.
com.springsource.net.sf.cglib-2.2.0.jar
↩
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.3.jar
ehcache-core-2.4.3.jar Shiro的源码包中不自带这个包,需要手动找到添加至项目.
log4j-1.2.15.jar
shiro-aspectj-1.2.2.jar
shiro-cas-1.2.2.jar
shiro-core-1.2.2.jar
shiro-ehcache-1.2.2.jar
shiro-guice-1.2.2.jar
shiro-quartz-1.2.2.jar
shiro-spring-1.2.2.jar
shiro-tools-hasher-1.2.2-cli.jar
shiro-web-1.2.2.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
0 0
- Spring集成Shiro HelloWorld之初步实现登陆及验证
- Spring boot 整合shiro 实现登陆验证
- SSH集成shiro实现登陆
- Spring Shiro登陆验证技术详解
- shiro 权限认证框集成到spring中,实现登陆与权限拦截
- Shiro整合Spring实现登录验证和授权之入门
- Shiro权限框架及与Spring集成
- Shiro简介及与spring集成
- Shiro简介及与spring集成
- spring集成shiro实现登录认证自定义验证功能(认证采用国密SM4算法)
- spring boot 集成shiro记住我实现
- spring 集成shiro 之 自定义过滤器
- spring 集成shiro 之 自定义过滤器
- spring 集成shiro 之 自定义过滤器
- spring 集成shiro 之 自定义过滤器
- spring 集成shiro 之 自定义过滤器
- shiro框架之与Spring集成
- Spring MVC + Shiro 实现权限验证
- 推荐系统大师项亮都来了,就问你约不约?
- 从inotify机制说到FileObserver实现原理
- 网络编程学习笔记一:Socket编程
- 如何在Java中构造多维动态数组以及多维动态数组的使用
- HDU 3974 Assign the task(并查集)
- Spring集成Shiro HelloWorld之初步实现登陆及验证
- hadoop机架感知
- LeetCode--No.20--Valid Parentheses
- 机器学习这么火,想跳坑该怎么做?
- 陶哲轩实分析-第18章 Lebesgue积分
- Implement Stack using Queues
- 【日志7.13】
- Meta http-equiv属性详解
- LeetCode--No.38--Count and Say