springmvc集成shiro登录失败处理操作

要将SpringMVC和Shiro集成起来,需要进行以下步骤:

1. 导入相关依赖

在项目的pom.xml文件中,需要添加spring-boot-starter-web、shiro-spring、shiro-core和thymeleaf等相关依赖。具体依赖版本可以自行选择,这里我给出一个示例:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.6.0</version>
  </dependency>
  <dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.6.0</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
  </dependency>
</dependencies>

2. 配置Shiro和SpringMVC

在Spring Boot应用程序中,可以在application.properties文件中配置Shiro和SpringMVC:

# Shiro配置
shiro.loginUrl = /login
shiro.successUrl = /index
shiro.unauthorizedUrl = /unauthorized

# SpringMVC配置
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.html

3. 编写Shiro配置类

Shiro的配置需要一个ShiroConfig类,通常继承自ShiroWebMvcConfigurerAdapter,这样可以将Shiro拦截器和SpringMVC的拦截器进行集成。

@Configuration
public class ShiroConfig {
  @Autowired
  private Environment env;

  @Bean
  public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
    ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
    shiroFilter.setSecurityManager(securityManager);

    shiroFilter.setLoginUrl(env.getProperty("shiro.loginUrl"));
    shiroFilter.setUnauthorizedUrl(env.getProperty("shiro.unauthorizedUrl"));

    Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

    filterChainDefinitionMap.put("/static/**", "anon");
    filterChainDefinitionMap.put("/logout", "logout");
    filterChainDefinitionMap.put("/**", "authc");

    shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
    return shiroFilter;
  }

  @Bean
  public DefaultWebSecurityManager securityManager() {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(shiroRealm());
    return securityManager;
  }

  @Bean
  public ShiroRealm shiroRealm() {
    ShiroRealm shiroRealm = new ShiroRealm();
    return shiroRealm;
  }

  @Bean
  public ShiroDialect shiroDialect() {
    return new ShiroDialect();
  }
}

4. 编写ShiroRealm类

ShiroRealm是实现Shiro用户身份验证和授权的核心,需要继承AuthorizingRealm类,实现doGetAuthenticationInfo和doGetAuthorizationInfo方法。

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

  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    // 授权
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    User user = (User) principals.getPrimaryPrincipal();
    authorizationInfo.setRoles(userService.getUserRoles(user.getUsername()));
    authorizationInfo.setStringPermissions(userService.getUserPermissions(user.getUsername()));
    return authorizationInfo;
  }

  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    // 身份验证
    UsernamePasswordToken upToken = (UsernamePasswordToken) token;
    String username = upToken.getUsername();
    User user = userService.getUserByUsername(username);
    if (user == null) {
      throw new UnknownAccountException("用户不存在!");
    }
    return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
  }
}

5. 编写用户服务类

用户服务类是指封装用户信息并提供相关服务的类,这里我假设UserService类已经完成并可用。

6. 编写登录控制器

登录控制器负责处理用户登录请求和跳转,登录表单也应该在此处处理。成功或失败后需要处理相应的逻辑。

@Controller
public class LoginController {

  @RequestMapping("/login")
  public String login(HttpServletRequest request) {
    String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
    String error = null;
    if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
      error = "用户名/密码错误";
    } else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
      error = "用户名/密码错误";
    } else if (AuthenticationException.class.getName().equals(exceptionClassName)) {
      error = "无效的用户名/密码";
    } else if (exceptionClassName != null) {
      error = "其他错误:" + exceptionClassName;
    }
    request.setAttribute("error", error);

    return "login";
  }

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

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

  @RequestMapping("/logout")
  public String logout() {
    Subject subject = SecurityUtils.getSubject();
    if (subject != null) {
      subject.logout();
    }
    return "redirect:/login";
  }
}

以上就是SpringMVC集成Shiro登录失败处理的完整攻略,具体过程还需要根据项目实际情况进行调整。以下是两个示例:

示例一:登录失败后跳转到同一页面,并提示错误信息

需要在控制器方法中添加shiroLoginFailure属性,并根据登录验证不通过的情况进行错误信息的提示:

@RequestMapping("/login")
public String login(HttpServletRequest request) {
  String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
  String error = null;
  if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
    error = "用户名/密码错误";
  } else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
    error = "用户名/密码错误";
  } else if (AuthenticationException.class.getName().equals(exceptionClassName)) {
    error = "无效的用户名/密码";
  } else if (exceptionClassName != null) {
    error = "其他错误:" + exceptionClassName;
  }
  request.setAttribute("error", error);

  return "login";
}

这样,在登录验证不通过的情况下,会自动跳转回登录页面,并提示相应的错误信息。

示例二:登录失败后跳转到不同页面,并提示错误信息

在控制器中添加ShiroFilterFactoryBean的unauthorizedUrl属性,将其指向不允许访问的页面即可。这样,在用户登录验证不通过或者没有权限的时候,会跳转到指定的页面。

@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
  ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
  shiroFilter.setSecurityManager(securityManager);

  shiroFilter.setLoginUrl(env.getProperty("shiro.loginUrl"));
  shiroFilter.setUnauthorizedUrl(env.getProperty("shiro.unauthorizedUrl"));

  Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

  filterChainDefinitionMap.put("/static/**", "anon");
  filterChainDefinitionMap.put("/logout", "logout");
  filterChainDefinitionMap.put("/admin", "roles[admin]");
  filterChainDefinitionMap.put("/**", "authc");

  shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
  return shiroFilter;
}

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

这样,在用户访问不允许访问的页面时,会自动跳转到unauthorized页面,并提示相应的错误信息。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springmvc集成shiro登录失败处理操作 - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • 关于JwtToken使用-重点看一下过期时间

    关于JwtToken的使用,过期时间是比较重要的一个因素。下面我会给出详细的攻略和示例。 什么是JwtToken? JwtToken是Json Web Token的缩写,是基于JSON的轻量级的身份验证和授权机制。它是以Base64编码的字符组成的字符串,包含了用户信息、Token过期时间以及加密算法等信息。 JwtToken在身份验证中有广泛的使用,比如在…

    Java 2023年5月20日
    00
  • JSP制作简单登录界面实例

    下面是在JSP中制作简单登录界面的完整攻略。 步骤1:创建JSP页面 首先,创建一个简单的JSP页面来显示登录表单。在该页面中添加必要的元素,如用户名、密码、提交按钮等。 示例代码: <!DOCTYPE html> <html> <head> <title>Login Page</title> &l…

    Java 2023年6月15日
    00
  • 使用JDBC连接Mysql数据库会出现的问题总结

    使用JDBC连接Mysql数据库会出现的问题总结 JDBC是Java针对各种关系型数据库提供的一种标准的接口,可以大大简化Java程序连接数据库的开发工作。但是,在使用JDBC连接Mysql数据库的过程中,常常会遇到一些问题。本篇攻略将会针对常见的问题进行总结,并给出相应的解决方案。 1. ClassNotFoundException 该异常通常在程序中出现…

    Java 2023年5月20日
    00
  • 重复提交、重复刷新、防止后退的问题以及处理方式分析

    重复提交 重复提交是指同一个表单或接口多次提交的情况,会导致数据异常或其他不可预知的问题。解决方案有两种: 方式一:使用token机制。在提交表单时,前端通过后端生成的token验证,确保表单只能提交一次。 方式二:使用状态跳转。在表单提交成功后,将页面跳转到一个新页面或者刷新当前页面,以避免用户进行二次提交。 重复刷新 重复刷新是指对同一个页面不断进行刷新…

    Java 2023年6月15日
    00
  • 一文详解Spring security框架的使用

    一文详解Spring security框架的使用 Spring Security是一个基于Spring框架实现的权限管理框架,支持基于角色的访问控制和安全性方面的许多其他功能,如认证、授权等等。本文将对Spring Security的使用进行详细讲解。 Spring Security的配置 在使用Spring Security之前,首先需要在pom.xml文…

    Java 2023年5月20日
    00
  • SpringMVC整合SpringSession 实现sessiong

    SpringMVC整合SpringSession 实现session 在Web应用程序中,Session是一种非常重要的机制,它可以帮助我们在不同的请求之间共享数据。SpringMVC提供了与SpringSession集成的支持,可以帮助我们更方便地管理Session。本文将详细介绍如何使用SpringMVC整合SpringSession实现Session管…

    Java 2023年5月17日
    00
  • 什么是堆区?

    以下是关于 Java 堆区的详细讲解和使用攻略: 堆区的作用是什么? Java 堆区(Heap)是一种用于存储对象实例的内存区域。堆区是线程共享的,其大小可以通过 -Xmx 和 -Xms 参数进行设置。 堆区的使用攻略 使用 Java 堆区,需要注意以下几点: 在程序开发中需要合理使用内存,避免出现内存泄漏和内存溢出等问题。 在实现自定义的类时,需要注意对象…

    Java 2023年5月12日
    00
  • 如何使用SpringSecurity保护程序安全

    当我们开发应用程序的时候,应该极力确保应用程序的安全性,因为数据安全至关重要。 SpringSecurity是一种开源安全框架,可以保护我们的应用程序,并确保具有良好的身份验证和授权,本文将详细讲解如何使用SpringSecurity保护程序安全。 SpringSecurity的基本概念 SpringSecurity是一种基于Servlet过滤器的安全框架,…

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