相关疑难解决方法(0)

如何在没有XML配置的情况下定义自定义AuthenticationEntryPoint

我已经苦苦挣扎了好几天了.我是Spring Boot的新手,并且喜欢不使用XML配置的想法.

我创建了一个RESTfull应用程序(使用JSON).我正在按照本教程正确配置身份验证.

我认为我设法使用Java配置重现几乎所有的配置,除了一件事 - AuthenticationEntryPoint

本教程使用http像这样的标记中的属性,并按以下方式定义formLogin:

<http entry-point-ref="restAuthenticationEntryPoint">

  <intercept-url pattern="/api/admin/**" access="ROLE_ADMIN"/>

  <form-login
     authentication-success-handler-ref="mySuccessHandler"
     authentication-failure-handler-ref="myFailureHandler"
  />

  <logout />

</http>
Run Code Online (Sandbox Code Playgroud)

Spring Security手册中AuthenticationEntryPoint解释说:

可以使用<http>元素上的entry-point-ref属性设置AuthenticationEntryPoint.

没有提到有关如何使用Java配置执行此操作的任何内容.

那么如何restAuthenticationEntryPoint在没有XML 的情况下"注册"我自己的,以防止在使用formLogin时重定向到登录表单?

下面我将提到我尝试过的内容.

谢谢你们.


在我的尝试中,发现你可以使用basicAuth定义它,如下所示:

@Configuration
@Order(1)                                                        
public static class RestWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {


        if (restAuthenticationEntryPoint == null) {
            restAuthenticationEntryPoint = new RestAuthenticationEntryPoint();
        }

        http
            .authorizeRequests()
                .antMatchers("/**").hasAnyRole(Sec.ADMIN,Sec.SUPER_USER)
...
        .and()
            .httpBasic()
                .authenticationEntryPoint(restAuthenticationEntryPoint)
Run Code Online (Sandbox Code Playgroud)

但我正在使用这样的表单登录(没有 …

java spring spring-security spring-boot

27
推荐指数
1
解决办法
3万
查看次数

返回HTTP错误401代码和跳过筛选链

使用自定义Spring Security过滤器,如果HTTP标头不包含特定的键值对,我想返回HTTP 401错误代码.

例:

public void doFilter(ServletRequest req, ServletResponse res,
                     FilterChain chain) throws IOException, ServletException {

   HttpServletRequest request = (HttpServletRequest) req;
   final String val = request.getHeader(FOO_TOKEN)

   if(val == null || !val.equals("FOO")) {
       // token is not valid, return an HTTP 401 error code
       ...
   }
   else {
    // token is good, let it proceed
    chain.doFilter(req, res);
   }
Run Code Online (Sandbox Code Playgroud)

据我了解,我可以做以下事情:

(1)((HttpServletResponse) res).setStatus(401)并跳过剩余的过滤链

要么

(2)抛出异常,最终导致Spring Security向客户端抛出401错误.

如果#1是更好的选择,如何在调用setStatus(401)响应后跳过过滤器链?

或者,如果#2是正确的方法,我应该抛出哪个例外?

spring-security

18
推荐指数
4
解决办法
2万
查看次数

处理Spring Boot Resource Server中的安全性异常

如何在纯资源服务器上获取我的自定义ResponseEntityExceptionHandlerOAuth2ExceptionRenderer处理Spring安全性引发的异常?

我们实施了一个

@ControllerAdvice
@RestController
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
Run Code Online (Sandbox Code Playgroud)

因此,只要资源服务器上出现错误,我们就希望它能够回答

{
  "message": "...",
  "type": "...",
  "status": 400
}
Run Code Online (Sandbox Code Playgroud)

资源服务器使用application.properties设置:

security.oauth2.resource.userInfoUri: http://localhost:9999/auth/user
Run Code Online (Sandbox Code Playgroud)

对我们的auth服务器进行身份验证和授权请求.

但是,任何弹簧安全性错误都将始终绕过我们的异常处理程

    @ExceptionHandler(InvalidTokenException.class)
    public ResponseEntity<Map<String, Object>> handleInvalidTokenException(InvalidTokenException e) {
        return createErrorResponseAndLog(e, 401);
    }
Run Code Online (Sandbox Code Playgroud)

并生产

{
  "timestamp": "2016-12-14T10:40:34.122Z",
  "status": 403,
  "error": "Forbidden",
  "message": "Access Denied",
  "path": "/api/templates/585004226f793042a094d3a9/schema"
}
Run Code Online (Sandbox Code Playgroud)

要么

{
  "error": "invalid_token",
  "error_description": "5d7e4ab5-4a88-4571-b4a4-042bce0a076b"
}
Run Code Online (Sandbox Code Playgroud)

那么如何配置资源服务器的安全性异常处理呢?我找到的只是如何通过实现自定义来自定义Auth服务器的示例OAuth2ExceptionRenderer.但我无法找到将其连接到资源服务器的安全链的位置.

我们唯一的配置/设置是这样的:

@SpringBootApplication
@Configuration
@ComponentScan(basePackages = {"our.packages"})
@EnableAutoConfiguration
@EnableResourceServer
Run Code Online (Sandbox Code Playgroud)

java security spring spring-security spring-boot

17
推荐指数
2
解决办法
2万
查看次数

Spring Security Oauth - OAuth2Exceptions 的自定义格式

spring security oauth 的错误格式符合 OAuth 规范,看起来像这样。

{
  "error":"insufficient_scope",
  "error_description":"Insufficient scope for this resource",
  "scope":"do.something"
}
Run Code Online (Sandbox Code Playgroud)

特别是在资源服务器上,我发现为身份验证问题获取不同的错误格式有点奇怪。所以我想改变这个异常的呈现方式。

文件说:

授权服务器中的错误处理使用标准的 Spring MVC 特性,即 @ExceptionHandler 方法

所以我尝试了这样的事情来自定义错误的格式:

@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyErrorHandler {

    @ExceptionHandler(value = {InsufficientScopeException.class})
    ResponseEntity<MyErrorRepresentation> handle(RuntimeException ex, HttpServletRequest request) {
        return errorResponse(HttpStatus.FORBIDDEN,
                MyErrorRepresentation.builder()
                        .errorId("insufficient.scope")
                        .build(),
                request);
    }
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用。

查看代码,所有的错误渲染似乎都是在DefaultWebResponseExceptionTranslator#handleOAuth2Exception. 但是实现自定义WebResponseExceptionTranslator不允许更改格式。

任何提示?

spring spring-security spring-security-oauth2

6
推荐指数
2
解决办法
6709
查看次数

Spring AuthenticationEntryPoint 返回 Tomcat HTML 错误而不是 JSON

我正在使用 Spring 在更大的应用程序中公开 API。当访问authentiated()配置后面的端点时,我的应用程序由于以下代码而抛出一个丑陋的Tomcat HTML错误:

@Component
public class EntryPointUnauthorizedHandler implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
            AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Access Denied");
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,由于这是一个 API,我只想返回 JSON,就像 API 的其余部分一样。对于正常的异常处理,我设置了以下内容@ControllerAdvice

@ControllerAdvice
public class DefaultExceptionHandler extends ResponseEntityExceptionHandler {

    /**
     * Default internal BadCredentialsException handler. Respond with 401 Unauthorized
     */
    @ExceptionHandler(value = BadCredentialsException.class)
    public ResponseEntity<Object> handleBadCredentialsException(BadCredentialsException e, WebRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        return handleExceptionInternal(e, null, headers, HttpStatus.UNAUTHORIZED, request);
    }

    /**
     * …
Run Code Online (Sandbox Code Playgroud)

java spring spring-security

5
推荐指数
1
解决办法
4186
查看次数

如何处理 Spring Security 中过滤器抛出的自定义异常

我是 Spring Security 的新手。

我有一段代码,用于检查请求中是否传递了授权标头,如果缺少,则抛出异常。

public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    private static final String BEARER = "Bearer";

    public TokenAuthenticationFilter(RequestMatcher requiresAuthenticationRequestMatcher) {
        super(requiresAuthenticationRequestMatcher);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {
        String username = request.getParameter("username");
        String authorization = request.getHeader("AUTHORIZATION");

        if (!request.getRequestURI().equals(UniversalConstants.LOGIN_PATH)) {
            if (authorization == null || authorization.length() == 0 || !authorization.startsWith(BEARER)) {
                throw new InvalidCredentialsException("Missing authentication token"); //<-----------------
            }

        }

        String password = request.getParameter("password");
        return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(username, password));
    }
Run Code Online (Sandbox Code Playgroud)

我的目标是在全球范围内处理所有异常,因此我使用@ControllerAdvice。

注意:我知道 @ControllerAdvice 不适用于从 …

spring exception spring-security spring-boot

3
推荐指数
1
解决办法
6463
查看次数

如何处理 UsernameNotFoundException spring security

怎么处理UsernameNotFoundException

在 spring security 中,当找不到用户名时,UserDetailsService实现会抛出一个UsernameNotFoundException. 例如像这样:

   @Override
   @Transactional
   public UserDetails loadUserByUsername(java.lang.String username) throws UsernameNotFoundException {
       logger.info("Load user by username: {}", username);
       User user = userRepository.findUserByUsername(username).orElseThrow(
                   () -> new UsernameNotFoundException("User Not Found with -> username or email: " + username));

       return UserPrinciple.build(user);
   }
Run Code Online (Sandbox Code Playgroud)

我想构建一个自定义的“用户未找到 REST 响应”。我应该如何捕获/处理这个异常?我在 WebSecurityConfigurerAdapter 实现处理程序中实现了一个处理程序方法:

  private static void handleException(HttpServletRequest req, HttpServletResponse rsp, AuthenticationException e)
           throws IOException {
       PrintWriter writer = rsp.getWriter();
       writer.println(new ObjectMapper().writeValueAsString(new AuthResponse("", null, null, null, null,
               "Authentication failed.", false)));
       rsp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); …
Run Code Online (Sandbox Code Playgroud)

java spring exception spring-security spring-boot

1
推荐指数
1
解决办法
6054
查看次数