Java项目增加Shiro

简介

Shiro是一个强大而灵活的Java安全框架,用于认证、授权和会话管理。它为开发者提供了一套易于使用的API,可以轻松地将安全功能集成到Java应用程序中。

本文将介绍如何在Java项目中使用Shiro来增加安全性。

安装Shiro

首先,我们需要将Shiro添加到Java项目的依赖中。可以通过Maven或手动下载添加Shiro的jar包。

  1. 添加Maven依赖:
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.8.0</version>
</dependency>
  1. 手动下载添加jar包: 可以从官方网站(

使用Shiro进行认证

Shiro提供了多种认证方法,本文将使用最常见的用户名密码认证。

  1. 创建Shiro配置文件 首先,创建一个shiro.ini文件,并在其中配置认证相关的信息:
[main]
# 使用自定义的Realm
authenticator = org.apache.shiro.authc.credential.SimpleCredentialsMatcher

[users]
# 配置用户名和密码
admin = password123
  1. 创建自定义Realm
public class MyRealm extends AuthorizingRealm {
    // 验证用户信息
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());

        // 根据用户名查询用户信息
        User user = userRepository.findByUsername(username);

        // 用户不存在
        if (user == null) {
            throw new UnknownAccountException();
        }

        // 验证密码
        if (!password.equals(user.getPassword())) {
            throw new IncorrectCredentialsException();
        }

        // 返回认证信息
        return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
    }

    // 授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取用户名
        String username = (String) principals.getPrimaryPrincipal();

        // 查询用户角色和权限
        Set<String> roles = roleRepository.findRolesByUsername(username);
        Set<String> permissions = permissionRepository.findPermissionsByUsername(username);

        // 创建授权信息
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roles);
        authorizationInfo.setStringPermissions(permissions);

        return authorizationInfo;
    }
}
  1. 添加Shiro过滤器
public class ShiroFilterConfig extends DelegatingFilterProxy {

    @Override
    protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
        SecurityManager securityManager = wac.getBean("securityManager", SecurityManager.class);
        setTargetFilterLifecycle(true);
        setTargetBeanName("shiroFilter");
        setTargetFilterChainResolver(new PathMatchingFilterChainResolver());
        return super.initDelegate(wac);
    }
}
  1. 配置ShiroFilter
@Configuration
public class ShiroConfig {

    @Bean
    public MyRealm myRealm() {
        return new MyRealm();
    }

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

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        filterFactoryBean.setSecurityManager(securityManager());
        filterFactoryBean.setLoginUrl("/login");
        filterFactoryBean.setUnauthorizedUrl("/unauthorized");

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/admin/**", "authc, roles[admin]");
        filterChainDefinitionMap.put("/user/**", "authc, roles[user]");
        filterChainDefinitionMap.put("/**", "anon");

        filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return filterFactoryBean;
    }

    @Bean
    public ShiroFilterConfig shiroFilterConfig() {
        return new ShiroFilterConfig();
    }
}
  1. 在登录页面进行认证
public class LoginController {

    @PostMapping("/login")
    public String login(String username, String password) {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);

        try {
            subject.login(token);
            return "redirect:/home";
        } catch (AuthenticationException e) {
            return "redirect:/login?error";
        }
    }
}

以上代码将在登录时验证用户名和密码,并根据用户的角色授权