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日

相关文章

  • JAVA String.valueOf()方法的用法说明

    JAVA String.valueOf()方法的用法说明 简介 String.valueOf()方法是Java中的一个静态方法,用于将参数转换成字符串类型,该方法有多个重载版本,可以将各种类型的数据转换成字符串类型。 方法签名 public static String valueOf(boolean b) public static String value…

    Java 2023年5月27日
    00
  • JPA的多表复杂查询的方法示例

    JPA是Java Persistence API的缩写,它是Java EE中的一个API,提供了Java对象到关系数据库表之间的映射(ORM)功能。JPA中的多表复杂查询是指需要查询多个关联表的查询操作。下面将介绍JPA的多表复杂查询的方法示例。 一、JPA多表查询基本操作 定义多表查询的类 在JPA中,可以定义一个类来封装多表查询的结果,该类中包含了所有需…

    Java 2023年5月20日
    00
  • java如何交换这两个变量的值方法介绍

    下面我来为您详细讲解“java如何交换这两个变量的值方法介绍”。 在Java中,有多种方法可以交换两个变量的值,常见的方法有使用中间变量、使用加减法和使用异或运算。 使用中间变量交换变量值 这是一种最简单的方法,通过定义一个中间变量来存储变量值,然后交换两个变量的值。示例代码如下: int a = 10; int b = 20; int temp = a; …

    Java 2023年5月26日
    00
  • SpringBoot整合SpringSecurity实现认证拦截的教程

    首先,我们需要确保具备以下的环境: JDK 1.8+ Maven IntelliJ IDEA(或其他IDE) 接下来,我们可以按照以下步骤进行SpringBoot整合SpringSecurity实现认证拦截: 步骤一:创建SpringBoot工程 我们可以使用SpringBoot官方提供的Spring Initializr来创建工程,也可以使用IDEA的Ne…

    Java 2023年5月20日
    00
  • SpringBoot整合Freemarker实现页面静态化的详细步骤

    下面是详细的步骤: 1. 创建Spring Boot项目 可以使用Spring Boot官方提供的Spring Initializr快速生成一个基础项目。 2. 添加依赖 在pom.xml文件中添加Freemarker依赖: <dependency> <groupId>org.springframework.boot</grou…

    Java 2023年5月31日
    00
  • 关于Java的对象序列化流和反序列化流详细解读

    关于Java的对象序列化流和反序列化流详细解读 什么是对象序列化? 在Java中,对象序列化是指将一个对象转换为字节序列的过程,该字节序列可以被存储于磁盘上,或者将其传递到另一个网络节点中。对象序列化主要用于数据持久化或者网络传输。 如何进行对象序列化? Java提供了ObjectOutputStream类,它可以将Java对象转换为字节流。下面是一个对象序…

    Java 2023年5月26日
    00
  • Java File类提供的方法与操作

    首先我们来讲解Java的File类提供的方法与操作。File类是Java语言中常用的文件操作类,可以实现文件或目录的创建、删除、重命名等操作。下面是File类提供的一些常用方法: 1. 路径和文件名 1.1 getPath() 获取文件路径。 File file = new File("test.txt"); System.out.pri…

    Java 2023年5月20日
    00
  • java打印菱形及直角和等腰三角形的方法

    下面是“java打印菱形及直角和等腰三角形的方法”的完整攻略。 打印等腰三角形 等腰三角形的特点是两边相等,可以用两层循环实现。外层循环控制行数,内层循环控制每行的打印字符数量。 示例一: public class Triangle { public static void main(String[] args) { int n = 5; for (int …

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