Spring Boot / Spring安全性AuthenticationEntryPoint未执行

时间:2016-09-15 13:51:18

标签: spring spring-security spring-boot

我创建了一个包含此方法的类JwtAuthenticationFilter:

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
    Authentication authentication = null;

    if(hasJsonToken(request)) {
        JwtAuthenticationToken jwtAuthenticationToken = new JwtAuthenticationToken(getJsonToken(request)); 
        authentication = getAuthenticationManager().authenticate(jwtAuthenticationToken);           
    } else {
        throw new AuthenticationCredentialsNotFoundException(AUTHENTICATION_CREDENTIALS_NOT_FOUND_MSG);
    }

    return authentication;
}

如果未提供JWT,则抛出AuthenticationCredentialsNotFoundException。我希望这会在我的AuthenticationEntryPoint中触发begin方法 - 看起来像这样:

@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException authException) throws IOException, ServletException {   
response.sendError(HttpStatus.UNAUTHORIZED.value(),HttpStatus.UNAUTHORIZED.getReasonPhrase());
}

开始方法没有被打电话。这是我的spring安全配置(或其中的一部分):

@Bean
public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
    return new RestAuthenticationEntryPoint();              
}

protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
        .exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint()).and()
        .csrf().disable()
        .authorizeRequests().antMatchers(AUTHORISED_SERVICE_REQUESTS_ANT_MATCHER).authenticated()
        .anyRequest().permitAll();      
}

不确定我在这里做错了什么,我希望有人向我指出。感谢

My SecurityConfig类扩展了WebSecurityConfigurerAdapter,并使用@Configuration和@EnableWebSecurity注释

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    ...
}

我正在使用春季靴子。

所以...最终我通过创建自定义AuthenticationFailureHandler并在我的Authentication F.ilter中注册它来获得我想要的行为

jwtAuthenticationFilter.setAuthenticationFailureHandler(new JwtAuthenticationFailureHandler());

我现在的问题是,这是正确的做法,AuthenticationEntryPoint和AuthenticationFailureHandler有什么区别?

2 个答案:

答案 0 :(得分:1)

AuthenticationEntryPointAuthenticationFailureHandler之间的区别在于,前者用于“告诉”未经身份验证的用户进行身份验证,例如,通过将他们重定向到登录表单。后者用于处理错误的登录尝试。

您的AuthenticationEntryPoint可能不会被调用,因为您引发了异常。如果用户尝试访问需要身份验证的端点而您没有抛出任何东西,则会调用该方法。在没有凭据的情况下,无需验证用户就足够了,您无需引发异常。

如果您要创建具有JWT身份验证的应用程序,则可能不想将用户重定向到任何地方,因此您可以使用org.springframework.security.web.authentication.HttpStatusEntryPoint或类似您的入口点来返回状态代码。

答案 1 :(得分:1)

这是我的代码,用于使用Spring Boot / JWT实现AuthenticationEntryPoint和AccessDeniedHandler。我希望这对任何人都有帮助。

AuthenticationEntryPoint

if(request()->hasFile(‘profile_image’)){    $fullFileName = request()->file(‘profile_image’)
->getClientOriginalName();

$path = request()->file(‘profile_image’)->storeAs(‘profilePhotos’, $fullFileName);
}

Now in the create method: 
$user = User::create([
 ‘userId’ => request(‘userId’),
  ‘email’ => request(‘email’),
  ‘name’ => request(‘name’),
 ‘password’ => Hash::make(request(‘password’)),
  ‘profile_image’ => $fullFileName,
 ]);

I keep getting the error below. Someone please help...thanks. Plus I have created Storage link multiple times and keep deleting and recreating. 
fopen(C:\xampp\htdocs\bluway\storage\app\public\profilePhotos\avatar.jpg): failed to open stream. No such file or directory

AccessDeniedHandler

@Component
public class AuthenticationEntryPointJwt implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException authenticationException) throws IOException {

        httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
        httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

        final Map<String, Object> body = new HashMap<>();
        body.put("code", HttpServletResponse.SC_UNAUTHORIZED);
        body.put("payload", "You need to login first in order to perform this action.");

        final ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(httpServletResponse.getOutputStream(), body);
    }
}

WebSecurityConfigurerAdapter

@Component
public class AccessDeniedHandlerJwt implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {

        httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);

        final Map<String, Object> body = new HashMap<>();
        body.put("code", HttpServletResponse.SC_FORBIDDEN);
        body.put("payload", "You don't have required role to perform this action.");

        final ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(httpServletResponse.getOutputStream(), body);
    }
}

您可以在我的GitHub上查看完整的代码

https://github.com/JonathanM2ndoza/Nginx-Docker-Spring-Boot/tree/master/security/src/main/java/com/jmendoza/wallet/security