Spring security with @RestController - JSONish CustomAuthenticationProvider 响应

标签 spring spring-mvc authentication spring-security

我对 Spring 尤其是 Spring Security 还很陌生。此应用程序是 Restful 应用程序。

以下是来自 @RestController 的片段:

@RequestMapping(value = "/new", method = RequestMethod.POST)
    @PreRegistration("new")
    @ResponseBody
    public ResponseEntity<Void> newUser(@RequestBody @Valid TempUser user, UriComponentsBuilder ucBuilder) {

        registerService.addUser(user);

        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(ucBuilder.path("/register/{userName}").buildAndExpand(user.getUserName()).toUri());
        return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
    }

以下是来自 CustomAuthenticationProvider 的片段:

@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException  {
    final String name = authentication.getName();
    final String password = authentication.getCredentials().toString();
    if (name.equals("admin") && password.equals("system")) {
        final List<GrantedAuthority> grantedAuths = new ArrayList<>();
        grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
        final UserDetails principal = new User(name, password, grantedAuths);
        final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths);
        return auth;
    } 
    else {
        throw new BadCredentialsException("NOT_AUTHORIZED");
    }
}

安全配置:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .requestCache()
            .requestCache(new NullRequestCache())
            .and()
        .httpBasic()
            .and()
        .csrf().disable();
}

我试图实现的是,当 CustomAuthenticationProvider 抛出异常时(例如“错误凭证”或“需要完全身份验证...”,我想自定义响应并返回到响应正文JSON 格式。

我所做的是创建一个新的异常并使用 AOP 调用它。但似乎不起作用。我还尝试使用 @ControllerAdvice,但它似乎不起作用,因为 CustomAuthenticationProvider 位于 Controller 之外(我猜)。

最佳答案

对此有更好的方法。您应该在 spring security 配置和类中添加 authenticationEntryPoint ,它实现 AuthenticationEntryPoint 接口(interface)。像这样的事情:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/login").permitAll()
            .anyRequest().authenticated()
            .and()
        .requestCache()
            .requestCache(new NullRequestCache())
            .and()
        .httpBasic()
        // --> begin change: new lines added
            .and()
        .exceptionHandling().authenticationEntryPoint(new AuthExceptionEntryPoint())
        // <-- end change
            .and()
        .csrf().disable();

}

AuthExceptionEntryPoint 类,用于生成 JSON Jackson使用的ObjectMapper:

public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, 
                         AuthenticationException authException) 
                         throws IOException, ServletException {

        List<String> errors = new ArrayList<>();
        errors.add("Unauthorized");
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.writeValue(response.getOutputStream(), errors);
        } catch (Exception e) {
            throw new ServletException();
        }
    }
}

有关 Spring Security 配置的更多信息,您可以阅读 Spring docs

关于Spring security with @RestController - JSONish CustomAuthenticationProvider 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37063342/

相关文章:

java - 如何用空白页替换 Spring Boot 的 "Whitelabel Error Page"?

java - 自定义标签 - 访问模型中的数据?

.net - 在ASP.NET中开发自定义登录/身份验证系统的最佳方法是什么

authentication - 如何在 django-rest-framework 中使用 OAuth2?

java - 包 org.springframework.data.repository 不存在 spring boot jpa

Spring webflow - 访问 session

java - 为什么这个具有基于 java 的配置的 Spring 应用程序不能正常工作

java - Spring @RestController

java - 在 AWS Lambda 中使用的 IoC(控制反转)Java 框架

http - 身份验证在 MAPI/HTTP 中如何工作