shiro学习03-登录校验(1)

这一节说明shiro对登录模块的限制,这一节可能用到的接口有:SecurityManager,Realm,AuthenticationToken,AuthenticationInfo,PrincipalCollection,如果你对这些接口不熟悉的话,回到第一节先看看他们的大概介绍。

登录模块的大概流程很简单,用户提交用用名+密码,然后从数据库查找该用户,如果没有找到怎么样,找到了用户但是密码不对又怎么样。先将我搭建的shiro项目的pom.xml贴出,方便你的测试。在这个项目中我集成了spring+springMVC+shiro。

	<properties>
		<spring.version>4.1.6.RELEASE</spring.version>
		<junit.version>4.11</junit.version>
		<jackson.version>2.4.2</jackson.version>
  		<shiro.version>1.2.2</shiro.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>${jackson.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		 

		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-web</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>${shiro.version}</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.6.6</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.12</version>
		</dependency> 
	</dependencies>

 我们在实际项目中对shiro的使用是集成在spring中使用的,不会用到官网上提到的shiro.ini,因为没有人会将权限 角色定义在一个文档中,我将spring的xml的配置和项目的web.xml的配置贴出来,以做到我们的项目是一样的。

web.xml

<web-app>
	<!-- needed for ContextLoaderListener -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:beans.xml</param-value>
	</context-param>
 
	<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>*.do</url-pattern>
	</filter-mapping>
 
	<!-- Bootstraps the root web application context before servlet initialization -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<servlet>
		<servlet-name>springDispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
 
	<servlet-mapping>
		<servlet-name>springDispatcherServlet</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
 
</web-app>

 spring的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:p="http://www.springframework.org/schema/p"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	 http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context-3.0.xsd ">

	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<!-- override these for application-specific URLs if you like: <property 
			name="loginUrl" value="/login.jsp"/> <property name="successUrl" value="/home.jsp"/> 
			<property name="unauthorizedUrl" value="/unauthorized.jsp"/> -->
		<!-- The 'filters' property is not necessary since any declared javax.servlet.Filter 
			bean -->
		<!-- defined will be automatically acquired and available via its beanName 
			in chain -->
		<!-- definitions, but you can perform instance overrides or name aliases 
			here if you like: -->
		<!-- <property name="filters"> <util:map> <entry key="anAlias" value-ref="someFilter"/> 
			</util:map> </property> -->
		<!-- <property name="filterChainDefinitions"> <value> # some example chain 
			definitions: /admin/** = authc, roles[admin] /docs/** = authc, perms[document:read] 
			/** = authc # more URL-to-FilterChain definitions here </value> </property> -->
	</bean>
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<!-- Single realm app. If you have multiple realms, use the 'realms' property 
			instead. -->
		<property name="realm" ref="myRealm" />
		<!-- By default the servlet container sessions will be used. Uncomment 
			this line to use shiro's native sessions (see the JavaDoc for more): -->
		<!-- <property name="sessionMode" value="native"/> -->
	</bean>
	<bean id="myRealm" class="realm.MyRealm" />
</beans>

 其中MyRealm,因为我们这里仅仅是做登录,没有涉及到权限验证,所以直接继承自AuthenticatingRealm即可。代码如下:

public class MyRealm extends AuthenticatingRealm{

	private Map<String,String> db = new HashMap<String,String>();
	
	{
		db.put("张三","aaa");
		db.put("李四", "bbb");
	}	
	
	@Override    
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		final String username = (String) token.getPrincipal();
		final String password = db.get(username);
		if(db.get(username)==null){
			throw new UnknownAccountException();
		}
		AuthenticationInfo info = new AuthenticationInfo() {
			private static final long serialVersionUID = -1174132738824136785L;
			public PrincipalCollection getPrincipals() {
				SimplePrincipalCollection coll = new SimplePrincipalCollection(username,"DB");//暂时没有考虑中间修改用户名的情况
				Object o  = coll.getPrimaryPrincipal();//表示是从数据库中来的,这里的DB仅仅是象征意义,
				System.out.println(o.getClass().getName());
				return coll;
			}
			public Object getCredentials() {//暂时没有考虑中间修改密码的情况。
				return password;
			}
		};
		return info;
	}
}
这个是访问的controller
@Controller
public class ShiroControllerLogin {

	@ResponseBody
	@RequestMapping("/login.do")
	public String denglu(String username,String password,HttpSession session){
		UsernamePasswordToken token = new UsernamePasswordToken(username, password);
		Subject user = SecurityUtils.getSubject();
		try {
			user.login(token);	
		} catch (IncorrectCredentialsException e1) {
			return "密码不正确";
		}catch(UnknownAccountException e2){
			return "用户名不存在";
		}
		/**
		 * 你的登陆操作假设已经完成
		 */
		return "成功登陆";
	}	
}

 

 希望你也能做到跟我完全一样的代码,然后在下一节中我将尽可能多的查看shiro关于登录的源码。

猜你喜欢

转载自suichangkele.iteye.com/blog/2274961
03-