2 回答
TA贡献1805条经验 获得超9个赞
有没有一种方法,我只能在我的项目中使用身份验证部分,或者我应该使用这两个类在 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 的任何更改都可以在HttpSession
Web 请求结束时复制到(准备用于下一个 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 中过滤器的想法
TA贡献1829条经验 获得超9个赞
你必须写你的 userDetial 来告诉 spring 当前的用户授权和配置
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;
}
}
你必须将你的 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) {
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"));
}
}
添加回答
举报