Java 在Spring安全上下文中,身份验证和授权之间的区别是什么?
我正在从事一个java spring boot项目,我正在尝试使用JWT为用户身份验证设置spring安全性,我正在遵循的教程(以及我在internet上找到的许多教程和项目)讨论了两个部分—身份验证和授权 在大多数教程中,有两个过滤器类,一个处理身份验证,另一个处理授权! (我发现有些仅使用一个扩展了Java 在Spring安全上下文中,身份验证和授权之间的区别是什么?,java,spring-boot,authentication,spring-security,authorization,Java,Spring Boot,Authentication,Spring Security,Authorization,我正在从事一个java spring boot项目,我正在尝试使用JWT为用户身份验证设置spring安全性,我正在遵循的教程(以及我在internet上找到的许多教程和项目)讨论了两个部分—身份验证和授权 在大多数教程中,有两个过滤器类,一个处理身份验证,另一个处理授权! (我发现有些仅使用一个扩展了OncePerRequestFilterclass的类) 在具有两个过滤器类的项目中, 身份验证筛选器类扩展了UsernamePasswordAuthenticationFilter类。 授权类扩
OncePerRequestFilter
class的类)
在具有两个过滤器类的项目中,
身份验证筛选器类扩展了UsernamePasswordAuthenticationFilter类。
授权类扩展了基本身份验证筛选器类
是否有一种方法可以在我的项目中只使用身份验证部分,还是应该在SpringSecurity中使用这两个类来设置用户身份验证
任何解释都将不胜感激。您必须编写您的用户说明,告知spring当前的用户授权和配置
您必须将userDetailService更改为spring,以了解如何使用您的用户
@组件(“userDetailsService”)
公共类DomainUserDetailsService实现UserDetailsService{
私有最终记录器log=LoggerFactory.getLogger(DomainUserDetailsService.class);
私有最终用户存储库用户存储库;
公共域UserDetailsService(UserRepository UserRepository){
this.userRepository=userRepository;
}
@凌驾
@交易的
public UserDetails loadUserByUsername(最终字符串登录){
调试(“验证{}”,登录);
String lowercaseLogin=login.toLowerCase(Locale.ENGLISH);
可选userByLoginFromDatabase=userRepository.findOneWithRolesByLogin(小写字母);
返回userByLoginFromDatabase.map(用户->新建MyUserDetails(用户))
.orelsetrow(()->new UsernameNotFoundException(“在数据库中找不到用户“+小写字母+”));
}
}
是否有一种方法可以在我的项目中只使用身份验证部分,还是应该在SpringSecurity中使用这两个类来设置用户身份验证
不,不存在仅验证部分的概念,您对spring安全性有错误的看法,spring安全性是关于配置的,无论是通过使用默认配置还是通过实现自定义配置。(AuthenticationFilters
,AuthenticationProviders
,AuthenticationToken
等)
Spring安全性是关于身份验证和授权的,Spring安全性是通过在web.xml中声明一个过滤器DelegatingFilterProxy来配置的(在Spring引导中,它将通过自动配置完成) Spring security在代理过滤器或Spring管理的bean方面,在应用程序之前放置了一道墙(HttpFireWall)。如果请求在身份验证和授权部分都成功,则该请求可以到达您的应用程序 1.身份验证是关于用户身份的。 它将经历
- 验证凭证或
- 正在验证授权标头内容或
- 正在验证与请求(JSESSIONID cookie)关联的cookie,即会话
- 如果上述任何一项都不匹配,则将用户标识为匿名用户
- 详细信息对象(有关身份验证请求的其他详细信息)
- 主体对象(
或UserDetails
或AuthenticatedPrincipal
)principal
- 凭证(通常是密码,但可以是与
相关的任何内容)AuthenticationManager
- 授权授权人的集合
- 和一个经过验证的布尔值李>
FilterSecurityInterceptor
,它几乎是从SecurityContext
获取Authentication
对象并获得授权权限列表(授予角色)的筛选器链中的最后一个,它将决定是否允许此请求到达请求的资源,通过与HttpSecurityConfiguration
中配置的允许AntMatcher进行匹配来做出决定
考虑401未授权和403禁止的例外情况。这些决策将在过滤器链的最后一个位置执行401未经授权:未经身份验证的用户试图访问安全资源。
403禁止:通过身份验证的用户试图访问受限资源。
未经身份验证的用户将被允许访问非限制性资源,并且不会出现未经授权的错误,但由
匿名身份验证筛选器
处理,该筛选器为未经身份验证的用户设置权限角色\u匿名
注意下面给出了过滤器的顺序。其中,
身份验证是@order-4
授权为@Order-9(最后一次) 来自文档
springsecurity有几个方面,您定义的模式将根据传入的请求进行测试,以决定如何处理请求。当
FilterChainProxy
决定请求应通过哪个筛选器链时,以及当FilterSecurityInterceptor
决定应用于请求的安全约束时,会发生这种情况。在针对您定义的模式进行测试时,了解该机制是什么以及使用了什么URL值是很重要的。过滤器排序
过滤器在链中定义的顺序非常重要。无论您实际使用的是哪种过滤器,顺序应如下:
1.
ChannelProcessingFilter
,因为它可能需要重定向到其他协议2. <斯特隆
public class MyUserDetails implements UserDetails {
/**
*
*/
private static final long serialVersionUID = 1L;
private User user;
public MyUserDetails(User user) {
this.user = user;
}
@Override
public String getUsername() {
return user.getLogin();
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getGrantedAuthorities();
}
@Override
public boolean isAccountNonExpired() {
return user.getActivated();
}
@Override
public boolean isAccountNonLocked() {
return user.getActivated();
}
@Override
public boolean isCredentialsNonExpired() {
return user.getActivated();
}
@Override
public boolean isEnabled() {
return user.getActivated();
}
}
public class JWTFilter extends GenericFilterBean {
private TokenProvider tokenProvider;
public JWTFilter(TokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String jwt = resolveToken(httpServletRequest);
if (StringUtils.hasText(jwt) && this.tokenProvider.validateToken(jwt)) {
Authentication authentication = this.tokenProvider.getAuthentication(jwt);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(servletRequest, servletResponse);
}
private String resolveToken(HttpServletRequest request){
String bearerToken1 = RequestUtil.getTokenFromHeader(request);
if (bearerToken1 != null) return bearerToken1;
String jwt = request.getParameter(JWTConfigurer.AUTHORIZATION_TOKEN);
if (StringUtils.hasText(jwt)) {
return jwt;
}
return null;
}
}
@Component("userDetailsService")
public class DomainUserDetailsService implements UserDetailsService {
private final Logger log = LoggerFactory.getLogger(DomainUserDetailsService.class);
private final UserRepository userRepository;
public DomainUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
@Transactional
public UserDetails loadUserByUsername(final String login) {
log.debug("Authenticating {}", login);
String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);
Optional<User> userByLoginFromDatabase = userRepository.findOneWithRolesByLogin(lowercaseLogin);
return userByLoginFromDatabase.map(user -> new MyUserDetails(user))
.orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the database"));
}
}