猿问

Spring Security 中的身份验证和授权有什么区别?

我正在开发一个 java spring boot 项目,我正在尝试使用 JWT 设置 spring security 以进行用户身份验证,我正在关注的教程(以及我在互联网上找到的许多教程和项目)讨论了两个部分-认证和授权

在大多数教程中,有两个过滤器类,一个处理身份验证,另一个处理授权!(我发现有些只有一个扩展OncePerRequestFilter类的类)。

在那些具有两个过滤器类的项目中,身份验证过滤器类扩展了UsernamePasswordAuthenticationFilter类。授权类扩展BasicAuthenticationFilter类。

有没有一种方法,我只能在我的项目中使用身份验证部分,或者我应该使用这两个类在 Spring Security 中设置用户身份验证?

任何解释将不胜感激。


Qyouu
浏览 99回答 2
2回答

Cats萌萌

有没有一种方法,我只能在我的项目中使用身份验证部分,或者我应该使用这两个类在 Spring Security 中设置用户身份验证?不,不存在只有身份验证部分的概念,您对 Spring Security 的看法是错误的,Spring Security 的全部内容都与使用默认配置或实现自定义配置有关。(AuthenticationFilters、、AuthenticationProviders等AuthenticationToken)Spring security 是关于身份验证和授权的,Spring security 是通过在 web.xml 中声明一个过滤器 DelegatingFilterProxy 来配置的(在 Spring boot 中,它将通过自动配置来完成)。Spring 安全性在代理过滤器或 Spring 托管 bean 方面将WALL ( HttpFireWall )放置在您的应用程序之前。如果请求在身份验证和授权部分都成功,则可以到达您的应用程序。1. 身份验证就是对用户的身份识别。它将经历验证凭证或验证授权标头内容或验证与请求关联的 cookie(JSESSIONID cookie),即会话如果以上都不匹配,则用户被识别为匿名。在此步骤中将Authentication 创建对象。从 auth 对象你可以得到详细信息对象(有关身份验证请求的其他详细信息)主要对象(UserDetails或AuthenticatedPrincipal或Principal)凭据(通常是密码,但可以是与 相关的任何内容AuthenticationManager)授予权限的集合和一个布尔值已验证。2. 授权就是访问决策。FilterSecurityInterceptor过滤器链中几乎最后一个会Authentication从过滤器链中获取对象SecurityContext并获得授予的权限列表(授予的角色),并且它将决定是否允许该请求到达所请求的资源,决定是通过与允许在HttpSecurityConfiguration.考虑例外情况 401-UnAuthorized 和 403-Forbidden。这些决定将在过滤器链的最后完成。401-UnAuthorized:未经身份验证的用户尝试访问受保护的资源。403-Forbidden:经过身份验证的用户尝试访问受限资源。未经身份验证的用户将被允许访问非受限资源,并且他不会收到 UnAuthorized 错误,但它是由为未经身份验证的用户AnonymousAuthenticationFilter设置权限来处理的。ROLE_ANONYMOUS注意下面给出了过滤器排序。其中,身份验证为 @order-4授权为 @Order-9(Last)Spring Security有几个区域,您定义的模式会针对传入请求进行测试,以便决定如何处理请求。当FilterChainProxy决定应通过哪个过滤器链以及决定FilterSecurityInterceptor对请求应用哪些安全约束时,就会发生这种情况。根据您定义的模式进行测试时,了解机制是什么以及使用什么 URL 值非常重要。过滤器排序过滤器在链中定义的顺序非常重要。无论您实际使用哪个过滤器,顺序都应如下:1. ChannelProcessingFilter,因为它可能需要重定向到不同的协议2. SecurityContextPersistenceFilter,因此可以在 Web 请求开始时在 SecurityContextHolder 中设置 SecurityContext,并且对 SecurityContext 的任何更改都可以在HttpSessionWeb 请求结束时复制到(准备用于下一个 Web 请求)3. ConcurrentSessionFilter,因为它使用该SecurityContextHolder功能,但需要更新SessionRegistry以反映来自主体的正在进行的请求4.身份验证处理机制- UsernamePasswordAuthenticationFilter、CasAuthenticationFilter、BasicAuthenticationFilter 等 - 以便可以修改 SecurityContextHolder 以包含有效的身份验证请求令牌5. ,SecurityContextHolderAwareRequestFilter如果您使用它来将 Spring Security 感知安装HttpServletRequestWrapper到您的 servlet 容器中6. RememberMeAuthenticationFilter,以便如果没有早期身份验证处理机制更新了SecurityContextHolder,并且请求提供了一个 cookie,使记住我服务能够发生,一个合适的记住的 Authentication 对象将被放置在那里7. AnonymousAuthenticationFilter,这样,如果没有早期的身份验证处理机制更新SecurityContextHolder,一个匿名的 Authentication 对象将被放置8.捕获ExceptionTranslationFilter任何 Spring Security 异常,以便返回 HTTP 错误响应或AuthenticationEntryPoint启动适当的响应9.FilterSecurityInterceptor保护 Web URI 并在访问被拒绝时引发异常只是为了提供一些 Spring Security 中过滤器的想法

PIPIONE

你必须写你的 userDetial 来告诉 spring 当前的用户授权和配置public class MyUserDetails implements UserDetails {/**&nbsp;*&nbsp;&nbsp;*/private static final long serialVersionUID = 1L;private User user;public MyUserDetails(User user) {&nbsp; &nbsp; this.user = user;}@Overridepublic String getUsername() {&nbsp; &nbsp; return user.getLogin();}@Overridepublic String getPassword() {&nbsp; &nbsp; return user.getPassword();}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {&nbsp; &nbsp; return user.getGrantedAuthorities();}@Overridepublic boolean isAccountNonExpired() {&nbsp; &nbsp; return user.getActivated();}@Overridepublic boolean isAccountNonLocked() {&nbsp; &nbsp; return user.getActivated();}@Overridepublic boolean isCredentialsNonExpired() {&nbsp; &nbsp; return user.getActivated();}@Overridepublic boolean isEnabled() {&nbsp; &nbsp; return user.getActivated();}}&nbsp;你的过滤器可能是这样的public class JWTFilter extends GenericFilterBean {private TokenProvider tokenProvider;public JWTFilter(TokenProvider tokenProvider) {&nbsp; &nbsp; this.tokenProvider = tokenProvider;}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)&nbsp; &nbsp; throws IOException, ServletException {&nbsp; &nbsp; HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;&nbsp; &nbsp; String jwt = resolveToken(httpServletRequest);&nbsp; &nbsp; if (StringUtils.hasText(jwt) && this.tokenProvider.validateToken(jwt)) {&nbsp; &nbsp; &nbsp; &nbsp; Authentication authentication = this.tokenProvider.getAuthentication(jwt);&nbsp; &nbsp; &nbsp; &nbsp; SecurityContextHolder.getContext().setAuthentication(authentication);&nbsp; &nbsp; }&nbsp; &nbsp; filterChain.doFilter(servletRequest, servletResponse);}private String resolveToken(HttpServletRequest request){&nbsp; &nbsp; String bearerToken1 = RequestUtil.getTokenFromHeader(request);&nbsp; &nbsp; if (bearerToken1 != null) return bearerToken1;&nbsp; &nbsp; String jwt = request.getParameter(JWTConfigurer.AUTHORIZATION_TOKEN);&nbsp; &nbsp; if (StringUtils.hasText(jwt)) {&nbsp; &nbsp; &nbsp; &nbsp; return jwt;&nbsp; &nbsp; }&nbsp; &nbsp; return null;}}你必须将你的 userDetailService 更改为 spring 知道如何laod你的用户@Component("userDetailsService")public class DomainUserDetailsService implements UserDetailsService {private final Logger log = LoggerFactory.getLogger(DomainUserDetailsService.class);private final UserRepository userRepository;public DomainUserDetailsService(UserRepository userRepository) {&nbsp; &nbsp; this.userRepository = userRepository;}@Override@Transactionalpublic UserDetails loadUserByUsername(final String login) {&nbsp; &nbsp; log.debug("Authenticating {}", login);&nbsp; &nbsp; String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);&nbsp; &nbsp; Optional<User> userByLoginFromDatabase = userRepository.findOneWithRolesByLogin(lowercaseLogin);&nbsp; &nbsp; return userByLoginFromDatabase.map(user -> new MyUserDetails(user))&nbsp; &nbsp; &nbsp; &nbsp; .orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the database"));}}
随时随地看视频慕课网APP

相关分类

Java
我要回答