apache shiro是一款强大的,开源的认证,授权,加密,和会话管理的框架,
1.shiro四大核心功能介绍
- Authentication:认证,通过输入指定的口令在服务器上获取权限,这一操作被称为认证,其实也就是登陆
- Autheorization:授权,即权限验证,验证用户是否拥有执行某一操作的权限,即判断某一用户是否能做某一件事,通过是判断用户是否拥有某一角色,
- Cryptography:加密,既对用户存入的数据进行加密处理,而不是使用明文,
shiro的三个核心组件:Subject, SecurityManager 和 Realms.
百度百科中给出的概念如下,
- Subject:即“当前操作用户”,因为虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。
- 它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
- Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
介绍完shiro框架,我们开始入门案例,
1.创建一个maven工程,当然,也可以到网上下载jar包
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>${shiro.version}</version>
</dependency>
</dependencies>
<properties>
<shiro.version>1.2.2</shiro.version>
</properties>
2.配置web.xml文件
需要配置shiro特定的过滤器,主要作用是把所有的bean交给spring管理,通过spring容器来管理filter的生命周期,通过spring注入的形式,来代理一个filter执行,主要目的是,找到在spring中维护的目标filter,
<!--配置shiro拦截器-->
<filter>
<filter-name>shiro</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiro</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置spring监听器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 指定spring配置文件的位置,配置文件放在resources下 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--上面是shiro跟spring的配置-->
<!--配置struts拦截器-->
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
spring文件applicationContext.xml配置
<?xml version="1.0" encoding="UTF-8"?><!-- @version $Id: applicationContext.xml 561608 2007-08-01 00:33:12Z vgritsenko $ -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<!--跟shiro整合-->
<!--配置过滤器-->
<bean id="shiro" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="loginUrl" value="/login.html"></property>
<property name="successUrl" value="/index.html"></property>
<property name="securityManager" ref="securityManager"></property>
<property name="unauthorizedUrl" value="/unauthorized.html"></property>
<!--设置规则-->
<property name="filterChainDefinitions">
<!--anon,不拦截的页面-->
<!--authc,需要登陆才能访问的页面-->
<value>
/css/** = anon
/images/** = anon
/js/** = anon
/validatecode.jsp* = anon
/userAction_login.* = anon
/**=authc
</value>
</property>
</bean>
<!--配置管理者,核心类-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="realm"></property>
</bean>
<!--配置realm-->
<bean id="realm" class="cn.itcast.realm.LoginRealm"></bean>
<!--开启注解扫描-->
<context:component-scan base-package="cn.itcast.demo"/>
<!-- 整合 spring data jpa -->
<jpa:repositories base-package="cn.itcast.bos.dao" />
<!--开启事务注解扫描-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!--连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="jdbc:oracle:thin:@192.168.129.100:1521:orcl"/>
<property name="user" value="xiaoyang"/>
<property name="password" value="xy123"/>
</bean>
<!--spring 跟 jpa整合-->
<!--配置factory-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--包扫描-->
<property name="packagesToScan" value="cn.itcast.domain"/>
<!--持久层使用hibernate框架-->
<property name="persistenceProvider" >
<bean class="org.hibernate.ejb.HibernatePersistence"/>
</property>
<property name="jpaVendorAdapter">
<!-- 自动建表 -->
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="database" value="ORACLE"/>
<!--其实就是数据库方言-->
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect"/>
</bean>
</property>
<property name="jpaDialect">
<!--hql hqpl-->
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
</bean>
</beans>
编写action层,
@Namespace("/")
@ParentPackage("struts-default")
@Controller
@Scope("prototype")
public class UserAction extends BaseAction<User> {
@Action(value="userAction_login",results = {@Result(name = Constant.SUCCESS,location = "/index.html",type = "redirect")
,@Result(name = Constant.FAIL,location = "/login.html",type = "redirect") //
})
public String login() throws IOException {
try {
Subject subject = SecurityUtils.getSubject();//获取主体
//参数,账户, 密码
UsernamePasswordToken token = new UsernamePasswordToken(getModel().getUsername(),getModel().getPassword());
//使用主体登陆
subject.login(token); //如果没有登陆成功,抛出异常
//获取登陆对象,
User user = (User) subject.getPrincipal();
//保存状态
ServletActionContext.getRequest().getSession().setAttribute("loginUser", user);
log.info("成功");
}catch (Exception e){
//账户密码不正确
log.info("密码错误");
}
return Constant.SUCCESS;
}
}
编写realm类,
“`
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.Realm;
import javax.annotation.Resource;
public class LoginRealm extends AuthenticatingRealm {
@Resource
private IUserDao idao;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//下塑转型
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
//获取前端传来的账号
String username = token.getUsername();
User user = idao.findByUsername(username);
if (user == null){
//账户不存在
return null;
}
return new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
}
}
以上就是登陆的核心代码,是不是很简单呢?