gpt4 book ai didi

java - 编写具有 REST 功能的 AuthenticationFilter 的最佳方法是什么?

转载 作者:太空宇宙 更新时间:2023-11-04 12:17:44 24 4
gpt4 key购买 nike

下面是我到目前为止所拥有的,但它没有达到我想要的效果。如果内容类型不是 json,我想要的是 415,并且 400 jackson 无法反序列化或者验证错误。当然,目前这都是 401,而且我在反序列化方面做了一些错误的事情(将错误的类型传递给 json)。我认为可能有某种方法可以利用 Spring MVC 在常规 Controller 的底层执行的操作。

@Component
public class JsonAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

private final ObjectMapper objectMapper;
private final Validator validator;

protected JsonAuthenticationFilter( final ObjectMapper objectMapper, final Validator validator ) {
super( new AntPathRequestMatcher( "/authentication/password", "POST" ) );
this.objectMapper = objectMapper;
this.validator = validator;
}

@Override
public Authentication attemptAuthentication( final HttpServletRequest request, final HttpServletResponse response )
throws AuthenticationException, IOException, ServletException {

if ( request.getContentType() == null
|| !MediaType.APPLICATION_JSON.isCompatibleWith( MediaType.parseMediaType( request.getContentType() ) ) ) {
response.setStatus( HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE );
throw new AuthenticationServiceException(
"Media Type not supported: " + request.getContentType() );
}

PasswordCredentials credentials = objectMapper.readValue( request.getReader(), PasswordCredentials.class );
DataBinder dataBinder = new DataBinder( credentials );
dataBinder.setValidator( validator );
dataBinder.validate();

AbstractAuthenticationToken authRequest = credentials.toAuthenticationToken();

setDetails( request, authRequest );

return this.getAuthenticationManager().authenticate( authRequest );
}

/**
* Provided so that subclasses may configure what is put into the authentication
* request's details property.
*
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have its details
* set
*/
protected void setDetails( HttpServletRequest request, AbstractAuthenticationToken authRequest ) {
authRequest.setDetails( authenticationDetailsSource.buildDetails( request ) );
}

@Override
@Autowired
public void setAuthenticationManager( final AuthenticationManager authenticationManager ) {
super.setAuthenticationManager( authenticationManager );
}
}

最佳答案

我猜您正在使用 JWT 身份验证,或者至少是某种基于 token 的身份验证,对吧?您最好使用将身份验证委托(delegate)给 authenticationManager@RestController,而不是使用较低级别的过滤器语义。

这是我之前使用过的 Controller ,稍作修改以符合您的 DTO。你会注意到它看起来很像 the suggested JHipster example :

@RestController
@RequestMapping(value = "/api")
public class LoginController {

private final Logger logger = LoggerFactory.getLogger(getClass());

private final AuthenticationManager authenticationManager;
private final TokenAuthenticationService tokenAuthenticationService;

public LoginController(
final AuthenticationManager authenticationManager,
final TokenAuthenticationService tokenAuthenticationService) {
this.authenticationManager = authenticationManager;
this.tokenAuthenticationService = tokenAuthenticationService;
}

@RequestMapping(
value = "/login",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE) // will cause 415 errors
public ResponseEntity<String> authenticate(
@Valid @RequestBody PasswordCredentials request) { // validated implicitly
try {
final User principal = doAuthenticate(request);
return ResponseEntity.ok(tokenFor(principal));
} catch (Exception e) {
logger.error("Error authenticating user", e);
return new ResponseEntity<>(HttpStatus.FORBIDDEN);
}
}

private String tokenFor(final User principal) {
return tokenAuthenticationService.createTokenForUser(principal);
}

private User doAuthenticate(PasswordCredentials request) {
final Authentication authentication = request.toAuthenticationToken();
final Authentication authenticated = authenticationManager.authenticate(authentication);
return (User) authenticated.getPrincipal();
}
}

要了解 Spring Controller 如何解析、解析和验证 JSON 请求正文参数,您应该查看 RequestResponseBodyMethodProcessor ,具体来说是 resolveArgument方法并在过滤器中实现类似的东西。但是,由于您的过滤器不是 Controller ,您应该通过删除对 MethodParameter 参数的所有引用来调整代码以满足您的需求。

关于java - 编写具有 REST 功能的 AuthenticationFilter 的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39194931/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com