filterchaindefinitions

filterchaindefinitions一、Shiro 简介Apache Shiro 是一个强大且易用的 Java 安全框架,执行身份验证、授权、密码和会话管理。使用 Shiro 的易于理解的 API,您可以快速、轻松地获得任何应用程序,从

一、Shiro 简介

Apache Shiro 是一个强大且易用的 Java 安全框架,执行身份验证、授权、密码和会话管理。使用 Shiro 的易于理解的 API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

二、Shiro 授权入门

简单介绍完毕 shiro 的作用后,接下来我们就直接进入 shiro 授权的入门,由于我们学习 shiro 重点是在使用,所以我们涉及到 shiro 源码的部分我们就不做过多的关注。

2.1:首先我们需要创建一个 maven 的 web 项目,导入 shiro 相关的依赖包和 tomcat 以及 jdk 的编译插件,本次我们使用 shiro 最新的依赖包。

大家也可以直接从 maven 的中央仓库找坐标

<groupId>cn.itcast</groupId>
<artifactId>shiro_quickStart</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<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>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8989</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>

2.2 在项目的 WEB-INF 下去创建一个 shiro 的配置文件 shiro.ini,同时需要在 web.xml 中配置 shiro 核心的过滤器;

filterchaindefinitions

2.2.1 web.xml 中核心过滤器配置

<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>

2.2.2 shiro.ini 配置认证

简单解释一下,users 是用来配置用户名和密码的,urls 是用来配置认证。/admin/**=authc 表示访问项目 admin 下面的所有资源都需要登录认证,而/login /login.jsp 表示访问这 2 个资源不需要登录认证;

 [main]
 [users] user=user admin=admin
 [urls]
 /admin/**=authc
 /login=anon
 /login.jsp=anon

2.2.3 编写 LoginServlet 和 login.jsp

* 在 pom.xml 中引入 Servlet 和 Jsp 的依赖包

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency> <dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>

* 创建 LoginServlet 和 login.jsp

filterchaindefinitions

filterchaindefinitions

*启动测试:

当我们访问 //localhost:8989/admin/aa,由于需要登录认证,所以跳转到了登录页面;

filterchaindefinitions

三、Shiro 入门配置细节

上一讲当我们访问//localhost:8989/admin/aa,由于访问的资源需要登录认证跳转到了 login.jsp;为什么跳转到 login.jsp 页面了呢?

原因是 shiro 使用了一些内置的过滤器;

filterchaindefinitions

我们可以通过查阅

filterchaindefinitions

源码,发现如果没有登录,自动跳转到 login.jsp

filterchaindefinitions

3.1 如何去配置登录页面;

filterchaindefinitions

3.2 如何让 shiro 完成登录认证(判断页面传入的用户名密码是正确的)

3.2.2 修改 login.jsp,加入表单,已经表单提交的地址

filterchaindefinitions

3.2.3 在 LoginServlet 完成登录认证

filterchaindefinitions

四、Shiro 授权入门

Shiro 除了可以完成认证外,也可以进行授权,即登录用户只有拥有指定的角色才能访问指定的资源;

4.1 修改 shiro.ini 文件,加入角色及授权。

filterchaindefinitions

4.2 [roles]中可以配置系统中的角色,此处我们定义了 2 个角色,一个角色为 ROLE_USER,一个为 ROLE_ADMIN

filterchaindefinitions

4.3[users]中除了可以配置登录的用户外,还可以给用户分配角色。此处我们定义 user 用户的角色为 ROLE_USER,admin 用户的角色为ROLE_ADMIN;

filterchaindefinitions

4. 4[urls]中除了可以配置资源访问是否需要登录认证,还可以配置登录用户访问资源需要哪些角色。此处我们定义访问/admin 下面的所有资源,除了需要登录,登录用户还需要有 ROLE_USER 角色;

filterchaindefinitions

4.5 测试我们发现如果使用 user/user 用户名和密码进行登录,登录成功后可以访问到/admin/add.jsp

filterchaindefinitions

而如果使用 admin/admin 用户名和密码进行登录登录成功后出现 401 的错误;

filterchaindefinitions

五、Shiro 认证流程和自定义 Realm

5.1 前 2 个章节我们已经讲解完毕,认证和授权的入门,接下来我们讲解认证流程;首先我们先来看一张图,授权流程图

filterchaindefinitions

流程:

1、当我们调用 Subject.login(token)进行登录,他会会自将 token 交由给 Security Manager,所以我们需要在调用 login 之前,在

SecurityUtils. setSecurityManager()设置 Security Manager;

2.SecurityManager 他会调用 Authenticator 进行用户名和密码的认证;

3、Authenticator 才是真正的身份验证者,Authenticator 会把相应的 token 传入 Realm,从 Realm 获取身份验证信息,如果没有返回/ 抛出异常表示认证失败了。

对于开发者来说;SecurityManager 和 Authenticator 都由 shiro 开发好了,当然他也提供了自己提供的一些 Realm 来获取用户名和密码;

默认情况下 shiro 使用的是 initRealm(shiro.ini 配置文件中配置的用户名和密码)进行同户名和密码的获取,我们也可以自己定义 Realm 来获取

用户名和密码完成认证;

5.2:自定义 Realm

package cn.itcast.realm;
import org.apache.shiro.authc.*; import org.apache.shiro.realm.Realm;
public class StaticRealm implements Realm {
@Override
public String getName() {
//指定Realm的名称
return "staticRealm";
}
@Override
public boolean supports(AuthenticationToken token) {
//该Realm支持的Token类型
return token instanceof UsernamePasswordToken;
}
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws
AuthenticationException {
//获取token中的用户名和密码
String username = String.valueOf(token.getPrincipal());
String password = new String((char[]) token.getCredentials());
//如果用户名密码不是gang/123抛出异常,认证失败
if(!username.equals("gang") || !password.equals("123")) { throw new AuthenticationException("用户名或者密码有误");
}
return new SimpleAuthenticationInfo(username,password,getName());
}
}

5.3 在 shiro.ini 中配置自定义的 Realm

filterchaindefinitions

5.4 测试自定义 Realm

经过测试我们发现原来的 iniRealm 就不再起作用,起作用的就是我们自定义的 Realm。

filterchaindefinitions

5.5 我们在定义 Realm 的时候除了可以实现 Realm 接口也使用它已经实现的一些类;Realm 的体系结构如下;

filterchaindefinitions

其中 JdbcRealm 可以完成基于数据库的认证;

5.6、使用 JdbcRealm 来完成基于数据库的认证;

5.6.1 导入 MySQL 驱动及连接池的依赖包,我们本次使用 Druid 连接池

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.14</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>

5.6.2 在 mysql 中创建 2 张数据库表、

filterchaindefinitions

表结构必须和 JdbcRealm 中发送 SQL 语句的表结构一致;

表 1:用户表、用来存储用户名和密码

filterchaindefinitions

表 2:角色表、用来存储用户的角色信息

filterchaindefinitions

5.6.3 在 shiro.ini 中配置 JdbcRealm

filterchaindefinitions

5.6.4:测试

filterchaindefinitions

六、Shiro 授权流程

6.1 上一讲我们给大家讲解了 Shiro 认证的流程,主要就是如何自定义 Realm,接下来我们要讲解的就是授权;首先我们看一张图授权流程图

filterchaindefinitions

流程如下:

1.首先当我们去调用 Subject.isPermitted*/hasRole*,他会调用 SecurityManager,而 SecurityManager 接着会调用 Authorizer 授权管理器;

2.Authorizer 是真正的授权者,如果我们调用如 isPermitted(“user:view”),其首先会通过 PermissionResolver 把字符串转换成相应的

Permission 实例;

3.在进行授权之前,其会调用相应的 Realm 获取 Subject 相应的角色/权限用于匹配传入的角色/权限;

4.Authorizer 会判断 Realm 的角色/权限是否和传入的匹配,如果有多个 Realm,会调用 ModularRealmAuthorizer 进行循环判断,如果匹配如 isPermitted*/hasRole*会返回 true,否 则返回 false 表示授权失败。

6.2 接下来我们通过一个入门案例,进行一个直观的感受;

6.2.2 首先我们先切换到 initRealm,注释掉 jdbcRealm。给 user/user 指定 ROLE_USER 角色、给 admin/admin 指定 ROLE_ADMIN 的角色

filterchaindefinitions

6.2.3 在用户登录成功后判断其是否有对应的角色

filterchaindefinitions

6.2.4 通过测试我们发现如果使用 admin/admin 登录,打印的是 true。

如果使用 user/user 登录,打印的是 false。

6.2.5 除了可以配置角色外,我们还可以配置权限;接下来我们来配置权限

filterchaindefinitions

ROLE_USER=user:* 、

表示 ROLE_USER 角色拥有 user:*的权限,*表示任意

ROLE_ADMIN=admin:*,user:*

表示 ROLE_AMIN 角色拥有 admin:*和 user:*的权限,*表示任意

/res/update.jsp=perms[user:add]

表示访问/admin/update.jsp 需要登录,并且需要 user:add 权限;

通过测试我们发现

user/user 和 user/admin 登录后都可以访问/res/update.jsp 资源但是 admin/admin 不能访问/admin/**下面的资源

6.2.6自定义Realm完成认证和授权。要想使用自定义Relam 完成认证和授权,建议继承AuthorizingRealm

public class MyAuthorizingRealm extends AuthorizingRealm {
/**
* 该方法是进行授权的
* @param principals
* @return
*/ @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//给登陆用户指定角色USER_ROLE
info.addRole("ROLE_ADMIN");
//给登录用户指定权限
info.addStringPermission("user:add");
return info;
}
/**
* 该方法是用来进行认证的
*/ @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
//如果用户名密码是gang/123
if(username.equals("gang") && password.equals("123")) { return new SimpleAuthenticationInfo(username, password, getName());
}else { throw new AuthenticationException("用户名或者密码错误");
}
}

6.2.6 配置自定义 Realm

filterchaindefinitions

6.2.6 测试;使用 gang/li 登录后拥有角色 ROLE_ADMIN 和权限 user:add.不能访问/admin/add.jsp 但是可以访问/res/update.jsp

七、Spring 整合 shiro

在实际开发中我们通常都不会单独使用 shiro,都是和 spring 进行整合,接下来我们要完成 spring 和 shiro 整合;

7.1:

导入 spring 和 shiro 整合相关依赖包

<dependency>
<groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.5.RELEASE</version>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>

7.2:编写 spring 的配置文件 applicationContext.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置自定义Releam-->
<bean id="myAuthorizingRealm" class="cn.itcast.realm.MyAuthorizingRealm"></bean>
<!--配置认证管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myAuthorizingRealm"></property>
</bean>
<!--配置shiro的过滤器-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/>
<!--登录页面-->
<property name="loginUrl" value="/login.jsp"/>
<!--登录成功后,跳转的页面-->
<property name="successUrl" value="/admin/add.jsp"/>
<!--未授权的页面-->
<property name="unauthorizedUrl" value="/401.jsp"/> <property name="filterChainDefinitions"> <value>
/admin/**=authc,roles[ROLE_USER]
/login=anon
/res/update.jsp=perms[user:add]
/logout=logout
</value>
</property>
</bean>
</beans>

7.2 在 web.xml 中使用 ContextLoaderListener 加载 spring 的配置文件.

<!--加载spring的配置文件-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--配置shiro的代理过滤器-->
<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>

学习资料:

权限管理实战:SpringBoot与Shiro整合

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/15533.html

(0)
上一篇 2024年 5月 19日
下一篇 2024年 5月 19日

相关推荐

关注微信