(转)Shiro配置、使用案例

 

一、配置环境

我这里使用的是maven在web环境下的配置 
附上maven依赖

你的工程slf4j_log4j12slf4j_apilog4jshiro_coreslf4j_apicommons_beanutilsyesnoyesnoyesno

1、使用Java SE环境的配置此

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.21</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.2.4</version>
</dependency>

2、使用Java EE环境的配置此

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.21</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-web</artifactId>
    <version>1.2.4</version>
</dependency>

3、不会使用maven的看我上一篇教程

http://blog.csdn.net/qq_32583189/article/details/51207873

4、懒得配置的自己去官网下jar包

http://central.maven.org/maven2/org/apache/shiro/shiro-web/1.2.4/shiro-web-1.2.4.jar 
http://mvnrepository.com/artifact/org.apache.shiro/shiro-core/1.2.4 
http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar 
http://central.maven.org/maven2/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar

二、配置文件 Shiro.ini

1,Shiro使用ini作为配置文件

在classPath(与包同级的目录,比如你的包com.doservlet.framework在src目录下,src就是你的classPath)目录下创建一个shiro.ini文件

[main]
authc.loginUrl=/login

[urls]
/=anon
/login=anon
/customer/**=authc

以上参数的意思

authc.loginUrl=/login

用户验证资源地址是/login

/=anon
/login=anon
/customer/**=authc

匿名用户可以访问/资源,/login资源 
但是/customer/下的所有资源都只能由验证过的用户访问 
这里等号左侧为资源,等号右侧是授权状态 
其实在原理是使用了过滤器,后面会讲到自己配置一个过滤器 
以下提供一些过滤器仅供参考

过滤器名称 功 能 配 置
anon 任何用户发送的请求都能够访问 -
authc 经过认证的请求可访问,否则将会将请求重定向到 ini 配置文件配置的 authc.loginUrl 资源,进行认证操作 authc.loginUrl=/login.jsp
authc.successUrl=/
#认证成功后重定向到此资源
authc.usernameParam=username
#从请求参数中获取key=username的value作为用户名
authc.passwordParam=password
#从请求参数中获取key=password的value作为密码
authc.rememberMeParam=rememberMe
#从请求参数中获取key=rememberMe的value作为是否记住密码的标识
logout 结束会话 logout.redirectUrl=/
#结束会话后重定向到此资源
port 指定请求端口 port=8080
#8080端口的请求可通过

2,注册Shiro

方式一,使用java代码(在一个可以执行初始化操作的地方,比如ServletContainerInitializer的子类的onStartUp方法里,或者一个注册了loadOnStartUp的Servlet的init方法里)

@Override
public void init(ServletConfig config) throws ServletException {
    ServletContext servletContext = config.getServletContext();
    //设置初始化参数
    servletContext.setInitParameter("shiroConfigLocation", "classPath:shiro.ini");
    //注册Listener
    servletContext.addListener(EnvironmentLoaderListener.class);
    //注册filter
    Dynamic dynamic = servletContext.addFilter("ShiroFilter", ShiroFilter.class);
    dynamic.addMappingForUrlPatterns(null, false, "/*");
}

方式二、在web.xml中配置

<context-param>
    <param-name>shiroConfigLocation</param-name>
    <param-value>classPath:shiro.ini</param-value>
</context-param>
<listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
    <filter-name>ShiroFilter</filter-name>
    <filter-class>com.doservlet.plugin.security.SmartSecurityFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>ShiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

三、使用Shiro

1,完善配置文件

使用之前需要在Shiro.ini文件中加上一些必要的信息 
因为验证身份的信息是存在数据库中的,所以这里需要告诉Shiro数据库信息 
这里需要使用者导入两个包一个是MySQL的桥接器,还是一个是数据库连接池 
maven使用

<!-- http://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.38</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.1.1</version>
</dependency>

也可以自行下载 
http://central.maven.org/maven2/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar 
http://central.maven.org/maven2/org/apache/commons/commons-dbcp2/2.1.1/commons-dbcp2-2.1.1.jar 
如果关于如何使用数据库还有问题,请先去学习。 
环境配置完成后在shiro.ini中添加信息

ds=org.apache.commons.dbcp2.BasicDataSource
ds.driverClassName=com.mysql.jdbc.Driver
ds.url=jdbc:///mydb
ds.username=root
ds.password=root

jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource=$ds

配置完这些后,你的Shiro就能访问到你的数据库了 
但是这还没完,因为你的Shiro并不知道你的数据表结构,所以你要给他指定sql语句 
假设你现在已经有了一个名为mydb的数据库,用户表 结构如下 
user

name type description
id int increment
username varchar 用户名
password varchar 密码

下面添加一个查询用户密码的语句到shiro.ini中

jdbcRealm.authenticationQuery=select password from user where username=?

Shiro还提供了一个强大的机制就是用户角色管理 
我们先创建一个表 role 里面存放角色名 
表结构

name type description
id int increment
role_name varchar 角色名

增加几条数据

id role_name
1 admin
2 student
3 teacher

现在我们还需要一张表来说明用户与角色的关系,名字就叫做user_role

name type description
id int increment
user_id int fk->user.id
role_id int fk->role.id

下面添加一个查询用户角色的语句到shiro.ini中

jdbcRealm.userRolesQuery=select role.role_name from user,user_role,role where user.id =user_role.user_id and role.id=user_role.role_id and user.username=?

Shiro提供用户角色管理的目的就是为了管理权限 
我们先创建一个表 permission 里面存放权限名 
表结构

name type description
id int increment
permission_name varchar 权限名

增加几条数据

id permission_name
1 read
2 update
3 delete

现在我们还需要一张表来说明用户角色与权限的关系,名字就叫做role_permission

name type description
id int increment
permission_id int fk->permission.id
role_id int fk->role.id

下面添加一个查询角色权限的语句到shiro.ini中

jdbcRealm.permissionsQuery=select permission.permission_name from role,role_permission,permission where role.id =role_permission.role_id and permission.id=role_permission.permission_id and role.role_name=?
jdbcRealm.permissionsLookupEnabled=true

现在将以上sql语句的配置注册到shiro的管理器中,只需要再加上一句话

securityManager.realms=$jdbcRealm

当然,Shiro频繁的数据库访问会有相当大的性能开销,这里我们在main中配置

cacheManager=org.apache.shiro.cache.MemoryConstrainedCacheManager
securityManager.cacheManager=$cacheManager

按照规范,开发人员不能在数据库中存储和使用明文密码,仍在在main中配置

passwordMatcher=org.apache.shiro.authc.credential.PasswordMatcher
jdbcRealm.credentialsMatcher=$passwordMatcher

既然在查询的时候我们使用了加密的方式,那么将密码存储到数据库中时我们只需要使用Shiro提供的接口

PasswordService service=new DefaultPasswordService();
String encryptedPassword = service.encryptPassword(password);
//只需要将encryptedPassword存入数据库 

2,登录

public static void login(String username, String password) {
    Subject currentUser = SecurityUtils.getSubject();
    if (currentUser != null) {
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        try {
            currentUser.login(token);
        } catch (Exception e) {
            l.error("login failure", e);
            throw new RuntimeException(e);
        }
    }
}

2,注销

public static void logout() {
    Subject currentUser = SecurityUtils.getSubject();
    if (currentUser != null) {
        currentUser.logout();
    }
}

结束语

这里只是基本的配置,后续还会有更深入的使用教程提供

转载请注明出处 scdn 陈小默 
http://blog.csdn.net/qq_32583189

猜你喜欢

转载自blog.csdn.net/weixin_41888813/article/details/81384596