117.info
人生若只如初见

怎样定制shiro框架认证流程

Apache Shiro 是一个强大且灵活的 Java 安全框架,用于身份验证、授权、加密和会话管理。要定制 Shiro 的认证流程,你需要遵循以下步骤:

1. 引入依赖

首先,在你的项目中引入 Apache Shiro 的依赖。如果你使用的是 Maven,可以在 pom.xml 文件中添加以下依赖:


    org.apache.shiro
    shiro-core
    1.8.0


    org.apache.shiro
    shiro-spring
    1.8.0

2. 配置 Shiro

创建一个 Shiro 配置类,通常命名为 ShiroConfig。在这个类中,你需要配置 Shiro 的各个组件,包括 SecurityManagerRealmAuthenticatorAuthorizerSessionManager

import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConfig {

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

    @Bean
    public JdbcRealm jdbcRealm() {
        JdbcRealm jdbcRealm = new JdbcRealm();
        // 配置数据源
        jdbcRealm.setDataSource(dataSource());
        // 配置 SQL 语句
        jdbcRealm.setConnectionCheckSQL("SELECT 1");
        jdbcRealm.setPermissionsLookupEnabled(true);
        return jdbcRealm;
    }

    @Bean
    public DataSource dataSource() {
        // 配置数据源,例如使用 HikariCP
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        dataSource.setUsername("username");
        dataSource.setPassword("password");
        return dataSource;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 配置过滤器链
        Map filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/admin/**", "authc"); // 需要认证的路由
        filterChainDefinitionMap.put("/**", "anon"); // 不需要认证的路由
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }
}

3. 自定义 Realm

在上面的配置中,JdbcRealm 是用于从数据库中获取用户信息和权限的。你可以通过继承 AuthorizingRealm 来实现自定义的认证和授权逻辑。

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.HashSet;
import java.util.Set;

public class CustomRealm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        // 查询用户的角色和权限
        Set roles = getRolesForUser(username);
        Set permissions = getPermissionsForUser(username);

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roles);
        authorizationInfo.setStringPermissions(permissions);
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();

        // 查询用户信息
        User user = getUserByUsername(username);
        if (user == null) {
            throw new UnknownAccountException("用户不存在");
        }

        return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
    }

    private Set getRolesForUser(String username) {
        // 实现获取用户角色的逻辑
        return new HashSet<>();
    }

    private Set getPermissionsForUser(String username) {
        // 实现获取用户权限的逻辑
        return new HashSet<>();
    }

    private User getUserByUsername(String username) {
        // 实现从数据库中获取用户的逻辑
        return new User();
    }
}

4. 自定义过滤器

Shiro 允许你自定义过滤器来实现特定的认证流程。你可以通过继承 org.apache.shiro.web.filter.authc.AuthenticatingFilter 来实现自定义的过滤器。

import org.apache.shiro.authc.*;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

public class CustomAuthenticatingFilter extends AuthenticatingFilter {

    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
        String username = getUsername(request);
        String password = getPassword(request);
        return new UsernamePasswordToken(username, password);
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        return executeLogin(request, response);
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        return false;
    }

    @Override
    protected void executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        try {
            getSubject(request, response).login(createToken(request, response));
        } catch (AuthenticationException e) {
            // 处理认证失败的情况
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"status\":\"error\",\"message\":\"认证失败\"}");
        }
    }
}

然后在 ShiroFilterFactoryBean 中配置这个自定义过滤器:

@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(securityManager);

    // 配置过滤器链
    Map filterChainDefinitionMap = new LinkedHashMap<>();
    filterChainDefinitionMap.put("/admin/**", "customAuthc"); // 使用自定义过滤器
    filterChainDefinitionMap.put("/**", "anon"); // 不需要认证的路由
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

    return shiroFilterFactoryBean;
}

5. 自定义认证逻辑

CustomAuthenticatingFilter 中,你可以实现自定义的认证逻辑,例如添加额外的验证步骤、处理不同的认证方式(如短信验证码、邮箱验证等)。

通过以上步骤,你可以定制 Shiro 的认证流程,以满足你的项目需求。

未经允许不得转载 » 本文链接:https://www.117.info/ask/fec4bAzsNAwFRBQ.html

推荐文章

  • 如何利用shiro框架做细粒度权限控制

    Apache Shiro 是一个强大且灵活的开源安全框架,它可以帮助你实现细粒度的权限控制。以下是一些关键步骤和概念,帮助你利用 Shiro 框架实现细粒度权限控制:

  • 怎样用shiro框架实现用户认证

    Apache Shiro 是一个强大且易用的 Java 安全框架,用于实现身份验证、授权、加密和会话管理。以下是使用 Shiro 框架实现用户认证的步骤: 添加依赖 在 Maven 项目...

  • 如何配置shiro框架权限管理

    Apache Shiro是一个强大且易用的Java安全框架,用于身份验证、授权、加密和会话管理。以下是配置Shiro框架权限管理的基本步骤:
    1. 添加依赖
    首先,在...

  • shiro框架springboot日志管理怎样做

    Apache Shiro 是一个强大且易用的 Java 安全框架,用于身份验证、授权、加密和会话管理。在 Spring Boot 应用程序中,结合 Shiro 进行日志管理可以通过以下步骤实...

  • 如何解决shiro框架与springboot冲突

    Apache Shiro 是一个强大且易用的 Java 安全框架,提供了认证、授权、加密和会话管理功能。而 Spring Boot 是一个用于简化 Spring 应用初始搭建以及开发过程的框...

  • shiro框架在springboot中的性能优化

    Apache Shiro 是一个强大且易用的 Java 安全框架,用于身份验证、授权、加密和会话管理。在 Spring Boot 中使用 Shiro 时,可以通过以下方法进行性能优化: 启用...

  • 怎样用shiro框架实现用户认证

    Apache Shiro 是一个强大且易用的 Java 安全框架,用于实现身份验证、授权、加密和会话管理。以下是使用 Shiro 框架实现用户认证的步骤: 添加依赖 在 Maven 项目...