掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务

springsecurity原理 spring security认证和授权流程

在当今的互联网应用中,安全性已经成为一个至关重要的因素。Spring Security 是一个广泛使用的安全框架,用于保护基于 Spring 的应用程序。它提供了强大的认证和授权机制,帮助开发者构建安全的应用系统。本文将详细介绍 Spring Security 的基本原理、认证和授权流程,帮助读者更好地理解和应用这一框架。

一、Spring Security 基本原理

  1. Spring Security 简介

Spring Security 是一个开源的安全框架,专为基于 Spring 的 Java 应用程序提供认证和授权功能。它基于 Servlet 过滤器(Filter)机制,通过拦截 HTTP 请求来进行安全控制。Spring Security 支持多种认证方式,如用户名/密码、OAuth2、LDAP 等,并提供了细粒度的权限管理功能。

  1. 核心概念

Authentication(认证):验证用户身份的过程。Spring Security 通过 AuthenticationManager 来处理认证请求。

Authorization(授权):确定已认证用户是否有权限执行特定操作的过程。Spring Security 通过 AccessDecisionManager 来处理授权请求。

Filter Chain(过滤器链):Spring Security 通过一系列的 Filter 来拦截 HTTP 请求,进行安全控制。

Security Context(安全上下文):存储当前用户的认证信息和授权信息。Spring Security 通过 SecurityContextHolder 来管理安全上下文。

  1. 核心组件

WebSecurityConfigurerAdapter:自定义安全配置的基础类,用于配置安全规则和过滤器链。

AuthenticationManager:处理认证请求的核心接口,负责验证用户身份。

UserDetailsService:提供用户详细信息的服务接口,通常用于从数据库或其他存储中加载用户信息。

AccessDecisionManager:处理授权请求的核心接口,决定用户是否有权限执行特定操作。

FilterChainProxy:Spring Security 的核心过滤器,负责管理过滤器链。

二、Spring Security 认证流程

  1. 认证流程概述

Spring Security 的认证流程主要分为以下几个步骤:

用户发起认证请求,通常是通过登录页面提交用户名和密码。

用户名和密码被传递给 AuthenticationManager 进行验证。

AuthenticationManager 将请求委托给具体的 AuthenticationProvider 进行认证。

如果认证成功,AuthenticationManager 返回一个已认证的 Authentication 对象。

认证结果被存储在 SecurityContext 中,供后续的授权检查使用。

  1. 具体步骤详解

用户发起认证请求:用户通过登录页面提交用户名和密码。例如,通过 HTML 表单提交 POST 请求到 /login 路径。

<form action="/login" method="post">
    <input type="text" name="username" placeholder="Username" />
    <input type="password" name="password" placeholder="Password" />
    <button type="submit">Login</button>
</form>

请求到达过滤器链:用户提交的请求首先到达 Spring Security 的过滤器链。Spring Security 通过一系列的 Filter 来处理请求,其中最重要的 Filter 是

UsernamePasswordAuthenticationFilter。
public class UsernamePasswordAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        // 提取用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 创建 Authentication 对象
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(username, password);
        // 将认证请求传递给 AuthenticationManager
        Authentication authentication = authenticationManager.authenticate(authenticationToken);
        // 存储认证结果
        SecurityContextHolder.getContext().setAuthentication(authentication);
        // 继续处理请求
        chain.doFilter(request, response);
    }
}

AuthenticationManager 处理认证请求:UsernamePasswordAuthenticationFilter将认证请求传递给 AuthenticationManager。AuthenticationManager 负责验证用户身份,并委托给具体的 AuthenticationProvider。

@Autowired
private AuthenticationManager authenticationManager;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
    try {
        // 创建 Authentication 对象
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword());
        // 认证请求
        Authentication authentication = authenticationManager.authenticate(authenticationToken);
        // 存储认证结果
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return ResponseEntity.ok(new AuthenticationResponse("Login successful"));
    } catch (Exception e) {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new AuthenticationResponse("Login failed"));
    }
}

AuthenticationProvider 进行认证:AuthenticationManager 将认证请求委托给具体的 AuthenticationProvider 进行认证。常见的 AuthenticationProvider 包括 DaoAuthenticationProvider 和 JwtAuthenticationProvider。

@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setUserDetailsService(userDetailsService);
    provider.setPasswordEncoder(passwordEncoder());
    return provider;
}

认证结果存储在 SecurityContext 中:如果认证成功,AuthenticationManager 返回一个已认证的 Authentication 对象。这个对象会被存储在 SecurityContextHolder 中,供后续的授权检查使用。

public class DaoAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        if (passwordEncoder.matches(password, userDetails.getPassword())) {
            return new UsernamePasswordAuthenticationToken(
                    userDetails,
                    null,
                    userDetails.getAuthorities()
            );
        }
        throw new BadCredentialsException("Invalid username or password");
    }
    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}

三、Spring Security 授权流程

  1. 授权流程概述

Spring Security 的授权流程主要分为以下几个步骤:

用户发起受保护资源的访问请求。

请求到达过滤器链,Spring Security 通过一系列的 Filter 来处理请求。

AccessDecisionManager 决定用户是否有权限访问受保护资源。

如果授权成功,用户可以访问受保护资源;否则,返回相应的错误信息。

  1. 具体步骤详解

用户发起访问请求:用户通过浏览器或其他客户端发起访问请求,请求受保护的资源。例如,访问 /admin/dashboard 页面。

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

请求到达过滤器链:用户提交的请求首先到达 Spring Security 的过滤器链。Spring Security 通过一系列的 Filter 来处理请求,其中最重要的 Filter 是

FilterSecurityInterceptor。
public class FilterSecurityInterceptor extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        // 提取请求路径
        String requestUrl = httpRequest.getRequestURI();
        // 检查权限
        if (!isAuthorized(requestUrl)) {
            httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied");
            return;
        }
        // 继续处理请求
        chain.doFilter(request, response);
    }
    private boolean isAuthorized(String requestUrl) {
        // 检查用户是否有权限访问该资源
        return accessDecisionManager.decide(
                SecurityContextHolder.getContext().getAuthentication(),
                requestUrl,
                getConfigAttributes(requestUrl)
        );
    }
}

AccessDecisionManager 决定授权:FilterSecurityInterceptor 会将请求路径传递给 AccessDecisionManager,AccessDecisionManager 负责决定用户是否有权限访问受保护资源。

@Bean
public AccessDecisionManager accessDecisionManager() {
    List<AccessDecisionVoter<?>> decisionVoters = new ArrayList<>();
    decisionVoters.add(new RoleVoter());
    decisionVoters.add(new AuthenticatedVoter());
    return new AffirmativeBased(decisionVoters);
}

授权结果处理:如果 AccessDecisionManager 决定用户有权限访问受保护资源,则请求继续处理;否则,返回相应的错误信息。例如,返回 403 Forbidden 错误。

public class RoleVoter implements AccessDecisionVoter<ConfigAttribute> {
    @Override
    public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
        for (ConfigAttribute attribute : attributes) {
            String role = attribute.getAttribute();
            if (authentication.getAuthorities().stream()
                    .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(role))) {
                return ACCESS_GRANTED;
            }
        }
        return ACCESS_ABSTAIN;
    }
}

springsecurity原理 spring security认证和授权流程

通过本文的学习,读者可以全面了解 Spring Security 的基本原理、认证和授权流程。Spring Security 是一个强大且灵活的安全框架,提供了全面的认证和授权机制,适用于各种应用场景。通过本文的介绍,读者可以掌握 Spring Security 的核心概念、认证和授权流程,以及如何进行自定义配置。希望本文的内容能够帮助读者更好地理解和应用 Spring Security,提升系统的安全性和可靠性。

声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com

  • 银行卡五元素校验

    验证银行卡、身份证、姓名、手机号是否一致并返回账户类型

    验证银行卡、身份证、姓名、手机号是否一致并返回账户类型

  • 全球天气预报

    支持全球约2.4万个城市地区天气查询,如:天气实况、逐日天气预报、24小时历史天气等

    支持全球约2.4万个城市地区天气查询,如:天气实况、逐日天气预报、24小时历史天气等

  • 购物小票识别

    支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景

    支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景

  • 涉农贷款地址识别

    涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。

    涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。

  • 人脸四要素

    根据给定的手机号、姓名、身份证、人像图片核验是否一致

    根据给定的手机号、姓名、身份证、人像图片核验是否一致

0512-88869195
数 据 驱 动 未 来
Data Drives The Future