SpringMVC+Shiro的基本使用及功能介绍

SpringMVC+Shiro的基本使用及功能介绍

什么是Shiro

Shiro是一个强大且易于使用的Java安全框架,它提供了身份验证、授权、加密、会话管理等功能,可以帮助我们快速构建安全的Web应用程序。

SpringMVC集成Shiro

SpringMVC集成Shiro可以帮助我们快速构建安全的Web应用程序。以下是SpringMVC集成Shiro的基本步骤:

步骤1:添加Shiro依赖

在pom.xml文件中添加Shiro依赖:

<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-core</artifactId>
  <version>1.7.1</version>
</dependency>

步骤2:配置ShiroFilter

在web.xml文件中配置ShiroFilter:

<filter>
  <filter-name>shiroFilter</filter-name>
  <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
  <init-param>
    <param-name>configPath</param-name>
    <param-value>classpath:shiro.ini</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>shiroFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

在上面的示例中,我们定义了一个名为“shiroFilter”的过滤器,并将它映射到“/*”路径。我们还指定了一个名为“shiro.ini”的配置文件,它将在ShiroFilter初始化时加载。

步骤3:配置Shiro安全管理器

在shiro.ini文件中配置Shiro安全管理器:

[main]
# 定义Realm
myRealm = com.example.shiro.MyRealm

# 定义安全管理器
securityManager = org.apache.shiro.web.mgt.DefaultWebSecurityManager
securityManager.realm = $myRealm

# 定义ShiroFilterFactoryBean
shiroFilterFactoryBean = org.apache.shiro.spring.web.ShiroFilterFactoryBean
shiroFilterFactoryBean.securityManager = $securityManager
shiroFilterFactoryBean.loginUrl = /login
shiroFilterFactoryBean.successUrl = /index
shiroFilterFactoryBean.unauthorizedUrl = /unauthorized
shiroFilterFactoryBean.filterChainDefinitions = /login = anon
/index = authc
/logout = logout
/unauthorized = anon
/** = authc

在上面的示例中,我们定义了一个名为“myRealm”的Realm,并将它配置到安全管理器中。我们还定义了一个名为“securityManager”的安全管理器,并将Realm配置到安全管理器中。我们还定义了一个名为“shiroFilterFactoryBean”的ShiroFilterFactoryBean,并将安全管理器配置到ShiroFilterFactoryBean中。我们还定义了登录URL、成功URL、未授权URL和过滤器链定义。

步骤4:编写Realm

在编写Realm时,我们需要继承org.apache.shiro.realm.AuthorizingRealm类,并实现doGetAuthorizationInfo()doGetAuthenticationInfo()方法。以下是一个简单的Realm示例:

public class MyRealm extends AuthorizingRealm {
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    // 获取当前用户信息
    String username = (String) principals.getPrimaryPrincipal();

    // 查询用户角色和权限信息
    Set<String> roles = new HashSet<>();
    Set<String> permissions = new HashSet<>();
    // ...

    // 创建AuthorizationInfo对象
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    authorizationInfo.setRoles(roles);
    authorizationInfo.setStringPermissions(permissions);
    return authorizationInfo;
  }

  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    // 获取用户名和密码
    String username = (String) token.getPrincipal();
    String password = new String((char[]) token.getCredentials());

    // 根据用户名查询用户信息
    User user = userService.getUserByUsername(username);
    if (user == null) {
      throw new UnknownAccountException("用户名或密码错误");
    }

    // 验证密码
    if (!password.equals(user.getPassword())) {
      throw new IncorrectCredentialsException("用户名或密码错误");
    }

    // 创建AuthenticationInfo对象
    SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
    return authenticationInfo;
  }
}

在上面的示例中,我们继承了AuthorizingRealm类,并实现了doGetAuthorizationInfo()doGetAuthenticationInfo()方法。在doGetAuthorizationInfo()方法中,我们获取当前用户信息,并查询用户角色和权限信息。在doGetAuthenticationInfo()方法中,我们获取用户名和密码,并根据用户名查询用户信息。如果用户不存在或密码不正确,将抛出异常。如果验证通过,我们将创建一个SimpleAuthenticationInfo对象,并返回。

示例

以下是一个使用SpringMVC+Shiro实现用户登录和权限控制的示例:

@Controller
public class UserController {
  @Autowired
  private UserService userService;

  @GetMapping("/login")
  public String login() {
    return "login";
  }

  @PostMapping("/login")
  public String doLogin(String username, String password) {
    Subject subject = SecurityUtils.getSubject();
    UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    try {
      subject.login(token);
      return "redirect:/index";
    } catch (AuthenticationException e) {
      return "login";
    }
  }

  @GetMapping("/index")
  public String index() {
    return "index";
  }

  @GetMapping("/admin")
  public String admin() {
    return "admin";
  }

  @GetMapping("/unauthorized")
  public String unauthorized() {
    return "unauthorized";
  }
}

public class User {
  private Integer id;
  private String username;
  private String password;
  private String role;
  // getter and setter
}

public class UserService {
  private List<User> userList = new ArrayList<>();

  public UserService() {
    User user1 = new User();
    user1.setId(1);
    user1.setUsername("admin");
    user1.setPassword("admin");
    user1.setRole("admin");
    userList.add(user1);

    User user2 = new User();
    user2.setId(2);
    user2.setUsername("user");
    user2.setPassword("user");
    user2.setRole("user");
    userList.add(user2);
  }

  public User getUserByUsername(String username) {
    for (User user : userList) {
      if (user.getUsername().equals(username)) {
        return user;
      }
    }
    return null;
  }
}

public class MyRealm extends AuthorizingRealm {
  @Autowired
  private UserService userService;

  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    // 获取当前用户信息
    String username = (String) principals.getPrimaryPrincipal();

    // 查询用户角色和权限信息
    Set<String> roles = new HashSet<>();
    Set<String> permissions = new HashSet<>();
    User user = userService.getUserByUsername(username);
    if (user != null) {
      roles.add(user.getRole());
      if ("admin".equals(user.getRole())) {
        permissions.add("user:read");
        permissions.add("user:write");
      } else if ("user".equals(user.getRole())) {
        permissions.add("user:read");
      }
    }

    // 创建AuthorizationInfo对象
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    authorizationInfo.setRoles(roles);
    authorizationInfo.setStringPermissions(permissions);
    return authorizationInfo;
  }

  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    // 获取用户名和密码
    String username = (String) token.getPrincipal();
    String password = new String((char[]) token.getCredentials());

    // 根据用户名查询用户信息
    User user = userService.getUserByUsername(username);
    if (user == null) {
      throw new UnknownAccountException("用户名或密码错误");
    }

    // 验证密码
    if (!password.equals(user.getPassword())) {
      throw new IncorrectCredentialsException("用户名或密码错误");
    }

    // 创建AuthenticationInfo对象
    SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
    return authenticationInfo;
  }
}

在上面的示例中,我们定义了一个名为“UserController”的控制器类,并使用@GetMapping注解来映射GET请求,@PostMapping注解来映射POST请求。我们还定义了一个名为“User”的JavaBean类,它包含了用户信息的属性和getter/setter方法。我们还定义了一个名为“UserService”的服务类,它用于查询用户信息。我们还定义了一个名为“MyRealm”的Realm,它用于身份验证和授权。我们还定义了一个名为“login.jsp”的登录页面,它包含了用户名和密码的输入框。我们还定义了一个名为“index.jsp”的首页,它包含了一个欢迎信息。我们还定义了一个名为“admin.jsp”的管理员页面,它包含了一个管理员信息。我们还定义了一个名为“unauthorized.jsp”的未授权页面,它包含了一个未授权信息。

总结

本文介绍了SpringMVC集成Shiro的基本步骤,并提供了一个使用SpringMVC+Shiro实现用户登录和权限控制的示例。通过本文的介绍,我们可以了解到如何在SpringMVC应用程序中使用Shiro实现安全控制。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringMVC+Shiro的基本使用及功能介绍 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • HttpClient基础解析

    HttpClient基础解析 什么是HttpClient? HttpClient是Apache软件基金会所提供的一个用于处理HTTP请求的第三方库。其提供了方便的API,使得我们可以通过代码实现HTTP请求的发送与响应的接收。 HttpClient的优点 简单易用:HttpClient提供了方便的API,使得我们可以通过简单的代码实现HTTP请求的发送与响应…

    Java 2023年5月20日
    00
  • java的Console类的使用方法及实例

    Java的Console类的使用方法及实例 什么是Console类? Java的java.io.Console类是用于读取控制台输入的类。在Java SE 5以前,读取控制台输入一般是使用System.in和Scanner类来实现的。但是这两种方式都有一些不足之处。使用System.in缺乏一些高级特性,比如输入密码时隐藏用户输入的内容;而使用Scanner…

    Java 2023年5月26日
    00
  • Java C++算法题解leetcode1592重新排列单词间的空格

    首先,我们需要明确题目的要求:将字符串中单词之间的空格重新排列,使得单词之间只有一个空格,同时字符串的首尾不含空格。 其次,我们需要分析和解决这个问题。首先,我们需要将原字符串按照空格分割成单词,然后将单词之间的空格删除或替换成一个空格,最后将字符串首尾空格删除即可。 以下是具体的代码解决方案: public String reorderSpaces(Str…

    Java 2023年5月19日
    00
  • PHP模拟登陆163邮箱发邮件及获取通讯录列表的方法

    下面是关于PHP模拟登陆163邮箱并进行发邮件、获取通讯录列表的详细攻略。 步骤一:模拟登陆163邮箱 首先,我们需要进行模拟登陆163邮箱。为了实现这个目标,我们可以采用CURL库来构建HTTP请求,并通过DOMDocument和SimpleXMLElement处理HTML和XML文档。下面是模拟登陆的详细步骤: 1. 准备登陆数据 我们需要准备一个数组来…

    Java 2023年6月16日
    00
  • Springboot集成ProtoBuf的实例

    下面是Spring Boot集成ProtoBuf的实例攻略,包括以下几个步骤: 添加依赖 在pom.xml文件中添加protobuf的依赖 <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</arti…

    Java 2023年5月26日
    00
  • 详解在Spring Boot中使用数据库事务

    以下是详解在Spring Boot中使用数据库事务的完整攻略: 1. 定义事务管理器 在使用Spring Boot进行数据库事务管理之前,需要使用Spring Framework的事务管理功能。为此,我们需要在Spring Boot项目中定义一个PlatformTransactionManager bean。 我们可以根据自己的数据库类型选择不同的事务管理器…

    Java 2023年5月20日
    00
  • Java源码刨析之ArrayDeque

    Java源码刨析之ArrayDeque Java中的ArrayDeque是一种基于动态数组的双端队列数据结构。本篇文章将与读者一起深入分析Java中ArrayDeque的源代码,从中学习这种数据结构的实现原理。 容量扩充 由于使用动态数组来存储队列中的元素,因此在添加元素时,需要判断是否需要扩展数组的容量。容量扩充的代码实现如下: private void …

    Java 2023年5月26日
    00
  • java(jdk)环境变量配置(XP、win7、win8)图文教程详解

    关于Java环境变量配置的详细攻略,我将为你提供如下步骤: 1. 下载安装JDK(Java Development Kit) 在安装JDK之前,请确认已经下载了适合你操作系统版本的JDK安装程序。可以在Oracle官网上下载最新版的JDK。 安装过程就是一般的软件安装过程,按照提示一步步操作即可。 2. 配置JAVA_HOME环境变量 安装完JDK后,我们需…

    Java 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部