Apache Shiro 1.3.2入门

简介
本示例依赖maven,使用ini文件作为应用程序的配置文件。
 
shiro配置
shiro的配置是从securityManager对象开始的,这个对象是线程安全且单个shiro应用只需要一个securityManager,因此Shiro提供了SecurityUtils让我们绑定它为全局的。
shiro提供了编程式的配置,如:
SecurityManager securityManager = new DefaultSecurityManager(realm);
//设置 authenticator
ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
securityManager.setAuthenticator(authenticator);
//设置 authorizer
ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
authorizer.setPermissionResolver(new WildcardPermissionResolver());
securityManager.setAuthorizer(authorizer);
SecurityUtils.setSecurityManager(securityManager);
 
不过,大多数应用程序都受益于基于文本的配置,这些配置可以独立于源代码进行修改,甚至可以让那些不熟悉Shiro API的人员更容易理解。为确保基于文本的通用配置机制能够在工作于所有最小的第三方依赖的环境中,Shiro支持INI格式来构建SecurityManager对象图及其支持组件。INI易于阅读,易于配置,设置简单,适合大多数应用。
ini 配置文件类似于Java中的properties,不同的是ini配置文件中的key是每个部分不重复即可,而不是整个配置文件,每个部分可以被看作是单个properties,注释符可以是“#”和“;”,ini配置包含以下几个部分:
[main]
定义应用程序的SecurityManager实例及它的任何依赖对象如Realm,按照出现的顺序执行,后边的覆盖前边的配置。对象定义格式为:对象名=全限定类名(相对于调用public无参构造器创建对象)。对象属性定义格式为:对象名.属性名=常量值(相当于调用对象setter方法设置常量值)、对象名.属性名=$对象名(相当于调用setter方法设置对象引用)。默认情况已经创建了一个名为securityManager的对象 , 类型为org.apache.shiro.mgt.DefaultSecurityManager,可以自定义,但对象名必须为securityManager。
对象嵌套注入,如:securityManager.sessionManager.globalSessionTimeout = 1800000
字节数组注入,由于字节数组不能以文本格式指定,因此我们必须使用字节数组的文本编码。默认是Base64,也可以在字符串前加上0x表示十六进制编码,如:securityManager.rememberMeManager.cipherKey = kPH+bIxk5D2deZiIxcaaaA==、
securityManager.rememberMeManager.cipherKey = 0x3707344A4093822299F31D008。
Array/Set/List注入,只需以逗号分隔常量值或对象引用,如:securityManager.sessionManager.sessionListeners = $sessionListener1, $sessionListener2。
Map注入,格式为map=key:value,key:value,keh和value可以是常量值和对象引用,常量值是字符串。
上述编程式的配置相当于:
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
authenticator.authenticationStrategy=$authenticationStrategy
securityManager.authenticator=$authenticator
authorizer=org.apache.shiro.authz.ModularRealmAuthorizer
permissionResolver=org.apache.shiro.authz.permission.WildcardPermissionResolver
authorizer.permissionResolver=$permissionResolver
securityManager.authorizer=$authorizer
 
[users]
定义一组静态的用户,包括用户名、密码、角色,这在用户数量非常少的环境或用户不需要在运行时动态创建的情况下非常有用,格式为:用户名=密码,角色1,角色2。密码是必须的,角色是可选的。
 
[roles]
定义一组静态的角色,包括角色、权限,这在角色数量非常少的环境或角色不需要在运行时动态创建的情况下非常有用,格式为:角色=权限1,权限2。
 
[urls]
用于web应用程序,提供了基于url 安全相关的配置,格式为:url=拦截器[参数],拦截器。
users和roles部分会分别被设置为org.apache.shiro.realm.text.IniRealm实例的users和roles属性。
 
maven配置
<?xml version="1.0" encoding="UTF-8"?>
 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
 
<groupId>com.xxx</groupId>
<artifactId>xxx-web-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
 
<name>xxx-web-demo Maven Webapp</name>
<url>http://www.example.com</url>
 
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
 
<build>
<finalName>xxx-web-demo</finalName>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</build>
 
<dependencies>
<dependency>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
 
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
 
<!--slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.25</version>
</dependency>
 
<!--javaee-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
 
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
 
示例
ShiroTestCase .java:
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class ShiroTestCase {
private final static Logger LOGGER = LoggerFactory.getLogger(ShiroTestCase.class);
 
@Test
public void test() {
//获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
 
//得到SecurityManager实例
SecurityManager securityManager = factory.getInstance();
 
//绑定SecurityManager实例到SecurityUtils
SecurityUtils.setSecurityManager(securityManager);
 
//得到Subject
Subject subject = SecurityUtils.getSubject();
 
//获取当前会话,如果会话不存在,就创建一个,相当于subject.getSession(true)
Session session = subject.getSession();
//设置会话的属性
session.setAttribute("someKey", "aValue");
 
//判断用户是否登录
if (!subject.isAuthenticated()) {
//创建用户名/密码身份验证Token
UsernamePasswordToken token = new UsernamePasswordToken("admin", "secret");
try {
//登录,即身份验证
subject.login(token);
LOGGER.info("登录成功");
} catch (AuthenticationException e) {
LOGGER.error("登录失败", e);
}
}
 
//从会话中获取属性
String value = (String) session.getAttribute("someKey");
if (value.equals("aValue")) {
LOGGER.info("会话有效");
}
 
//判断用户是否拥有指定的角色
if (subject.hasRole("admin")) {
LOGGER.info("有admin角色");
} else {
LOGGER.info("没有admin角色");
}
 
//判断用户是否拥有指定的权限
if (subject.isPermitted("user:create")) {
LOGGER.info("有user:create权限");
} else {
LOGGER.info("没有user:create权限");
}
 
//注销
subject.logout();
 
try {
//从会话中获取属性,如果已经注销,就会抛出异常
session.getAttribute("someKey");
} catch (UnknownSessionException e) {
LOGGER.error("会话无效", e);
}
}
}
 
执行结果:
[main] INFO org.apache.shiro.session.mgt.AbstractValidatingSessionManager - Enabling session validation scheduler...
 
[main] INFO shiro.ShiroTestCase - 登录成功
[main] INFO shiro.ShiroTestCase - 会话有效
[main] INFO shiro.ShiroTestCase - 有admin角色
[main] INFO shiro.ShiroTestCase - 有user:create权限
[main] ERROR shiro.ShiroTestCase - 会话无效
org.apache.shiro.session.UnknownSessionException: There is no session with id [741feb55-2b3c-4ea6-b332-e35e46572304]
at org.apache.shiro.session.mgt.eis.AbstractSessionDAO.readSession(AbstractSessionDAO.java:170)
at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSessionFromDataSource(DefaultSessionManager.java:236)
at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSession(DefaultSessionManager.java:222)
at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.doGetSession(AbstractValidatingSessionManager.java:118)
at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupSession(AbstractNativeSessionManager.java:148)
at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupRequiredSession(AbstractNativeSessionManager.java:152)
at org.apache.shiro.session.mgt.AbstractNativeSessionManager.getAttribute(AbstractNativeSessionManager.java:249)
at org.apache.shiro.session.mgt.DelegatingSession.getAttribute(DelegatingSession.java:141)
at org.apache.shiro.session.ProxiedSession.getAttribute(ProxiedSession.java:121)
at shiro.ShiroTestCase.test(ShiroTestCase.java:79)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

猜你喜欢

转载自www.cnblogs.com/gjb724332682/p/9240302.html