我有一个验证令牌的自定义筛选器tokenLoginFilter
我的Spring安全
<http pattern="/api/**" use-expressions="true" create-session="stateless" entry-point-ref="restAuthenticationEntryPoint" authentication-manager-ref="authenticationManager">
<custom-filter ref="tokenLoginFilter" position="FORM_LOGIN_FILTER" />
<!--<form-login authentication-success-handler-ref="mySuccessHandler" authentication-failure-handler-ref="myFailureHandler" />
<logout />-->
<intercept-url pattern="/api/**" access="isAuthenticated()" />
<intercept-url pattern="/api/login/**" access="permitAll"/>
</http>
令牌登录过滤器
@Component
public class TokenLoginFilter extends GenericFilterBean {
public static final String DEFAULT_TOKEN_AUTHENTICATION_PARAMETER_NAME = "token";
@Autowired
protected AuthenticationManager authenticationManager;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String[] parameters = request.getParameterValues(DEFAULT_TOKEN_AUTHENTICATION_PARAMETER_NAME);
if (parameters != null && parameters.length > 0) {
String token = parameters[0];
if (token != null && !token.isEmpty()) {
TemporaryAuthenticationToken temporaryAuthenticationToken = new TemporaryAuthenticationToken(token);
temporaryAuthenticationToken.setDetails(
new WebAuthenticationDetailsSource().buildDetails((HttpServletRequest) request));
SecurityContextHolder.getContext().setAuthentication(
authenticationManager.authenticate(temporaryAuthenticationToken));
}
}
chain.doFilter(request, response);
}
}
在authenticationmanager . authenticate调用中,我从TokenAuthenticationProvider中抛出了BadCredentialsException
令牌身份验证提供程序
@Component
public class TokenAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
public static final TimeZone DEFAULT_TIME_ZONE = getTimeZone("UTC");
@Autowired
protected TemporaryAuthenticationTicketService temporaryAuthenticationTicketService;
@Autowired
protected UsersService usersService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (authentication instanceof TemporaryAuthenticationToken) {
TemporaryAuthenticationTicket temporaryAuthenticationTicket = null;
try {
temporaryAuthenticationTicket = temporaryAuthenticationTicketService.find(
((TemporaryAuthenticationToken) authentication).getCredentials());
} catch (EmptyResultDataAccessException ignored) {
}
if (temporaryAuthenticationTicket != null) {
Calendar expirationDate = Calendar.getInstance(DEFAULT_TIME_ZONE);
expirationDate.setTime(temporaryAuthenticationTicket.getExpirationDate());
if (Calendar.getInstance(DEFAULT_TIME_ZONE).before(expirationDate)) {
Users users = usersService.findUsersUnsecure(temporaryAuthenticationTicket.getUserId());
if (users != null) {
UserDetails userDetails = new User(users);
return createSuccessAuthentication(userDetails, authentication, userDetails);
}
}
} else {
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
}
}
return null;
}
@Override
public boolean supports(Class<?> authentication) {
return TemporaryAuthenticationToken.class.isAssignableFrom(authentication);
}
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails,
UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
}
@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
return null;
}
}
Tomcat将此BadCredentialsException解释为错误代码500。
HTTP/1.1 500 Internal Server Error
Connection: close
Content-Language: en
Content-Length: 3152
Content-Type: text/html;charset=utf-8
Date: Tue, 08 Jul 2014 17:37:55 GMT
Server: Apache-Coyote/1.1
<html><head><title>Apache Tomcat/7.0.50 - Error report</title><style><!--H1 {fon
t-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:
22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525
D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;backgro
und-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;col
or:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:w
hite;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;backgroun
d:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR
{color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - Bad credentials
</h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>mes
sage</b> <u>Bad credentials</u></p><p><b>description</b> <u>The server encounter
ed an internal error that prevented it from fulfilling this request.</u></p><p><
b>exception</b> <pre>org.springframework.security.authentication.BadCredentialsE
xception: Bad credentials
com.neptune.unsub.security.TokenAuthenticationProvider.authenticate(Toke
nAuthenticationProvider.java:56)
org.springframework.security.authentication.ProviderManager.authenticate
(ProviderManager.java:156)
com.neptune.unsub.security.TokenLoginFilter.doFilter(TokenLoginFilter.ja
va:38)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doF
ilter(FilterChainProxy.java:342)
org.springframework.security.web.context.request.async.WebAsyncManagerIn
tegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequ
estFilter.java:106)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doF
ilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilte
r.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doF
ilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(Filte
rChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainPr
oxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(Dele
gatingFilterProxy.java:343)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(Delegating
FilterProxy.java:260)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(H
iddenHttpMethodFilter.java:77)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequ
estFilter.java:106)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(
CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequ
estFilter.java:106)
com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:169)
com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:232)
</pre></p><p><b>note</b> <u>The full stack trace of the root cause is available
in the Apache Tomcat/7.0.50 logs.</u></p><HR size="1" noshade="noshade"><h3>Apac
he Tomcat/7.0.50</h3></body></html>
我试过使用Spring MVC处理异常的方式。
@ControllerAdvice
public class GlobalExceptionHandlers extends ResponseEntityExceptionHandler {
@ExceptionHandler(BadCredentialsException.class)
public ResponseEntity<String> badCredentialsException(BadCredentialsException e) {
return new ResponseEntity<>(e.getMessage(), UNAUTHORIZED);
}
}
但是异常没有被这个ExceptionHandler处理。我如何让Spring在Tomcat处理之前拦截这个异常?
您可以尝试在doFilter方法中捕获异常并通过实现AuthenticationFailureHandler的类来处理它。代码应返回正确的HTTP状态代码以及JSON格式的合适异常。
@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response,AuthenticationException exception) throws
IOException, ServletException {
response.setContentType( MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
ApiError authenticationError = new ApiError(HttpStatus.UNAUTHORIZED, exception.getMessage(), "Not Authenticated");
ObjectMapper objectMapper = new ObjectMapper();
response.getWriter().write(objectMapper.writeValueAsString(authenticationError));
};
ApiError是一个自定义类,它包含返回异常场景所需的字段,以及正确的状态代码和异常消息字符串。
附注
您的GlobalExceptionHandler类将不起作用,因为它们已使用ControlllerAddge进行了注释,这意味着从Controller抛出的任何异常都在那里得到处理。
我是Spring Security的新手。 我有一段代码,我检查是否在请求中传递了授权头,如果缺少,我抛出一个异常。 我的目标是在全球范围内处理所有异常,因此我使用@ControllerAdvice。 注意:我知道@ControllerAdvice对于从这个和这个抛出的控制器之外的异常不起作用,所以我也遵循了这些链接中的建议。 重新验证入口点。Java语言 这是我配置authenticationE
我使用的是Nifi 0.4.1版本。我写自定义代码转换CSV到avro格式。我已经创建了类文件,并能够生成nar文件。将nar文件放置在lib目录中,并重新启动nifi服务器。 任何帮助都很感激.. 谢谢,
演示在网关追加一个header public class CustomFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 演示在网关追加heade
SOFARPC 提供了一套良好的可扩展性机制,为各个模块提供 SPI 的能力。 SOFARPC 对请求与响应的过滤链处理方式是通过多个过滤器 Filter 来进行具体的拦截处理,该部分可由用户自定义 Filter 扩展,自定义 Filter 的执行顺序在内置 Filter 之后。具体方式如下: Bolt Filter 新建自定义 Filter 。 public class CustomFilter
我正在使用Spring4和Tomcat。问题是有时我不得不在我的筛选器中抛出一个(自定义的)RuntimeException(控件甚至还没有到达控制器)。问题是,由于我没有抛出tomcat理解的异常,它被转换为500(内部服务器错误)。我相信403禁止会比500好(对于我的定制例外)。我查看了和注释。但只有当控件到达控制器时,这些才起作用。 到目前为止,我在筛选器的中将状态手动设置为403。有没有
问题内容: 我试图在Log4J2中实现和配置自定义过滤器- 基于ThresholdFilter,但打算做更多。我已经看到了有关自定义追加程序的主题,这些主题遵循相同的插件注释语法,但是还没有找到有关自定义拟合程序的主题。 MyCustomFilter.java (基于ThresholdFilter) log4j2.xml LoggingRunner.java 配置语法似乎与Apache文档中的语法