レスト サービス認証を基本認証からフォーム ベース認証に変換しようとしていますが、次のようなクエリ パラメータとして URL で認証の詳細を送信すると、以下のコードは正常に動作します (カスタム認証フィルタをコメントアウトしたことに注意してください)。http://localhost:8080/login?username=dfdf&&password=sdsdd
ただし、資格情報をクエリ パラメーターとして送信することに熱心ではなく、代わりに json として送信したいので、カスタム認証フィルターを作成しました。カスタム認証フィルターを追加すると、Spring セッションが機能しなくなります。x-auth-token
応答ヘッダーにフィールドが見つかりません。春のセッションとカスタム認証を一緒に有効にする方法、または資格情報のjson入力を処理するより簡単な方法かもしれません。
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private ObjectMapper objectMapper;
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/", "/register", "/index.html").permitAll().and().authorizeRequests()
.anyRequest().authenticated().and().requestCache().requestCache(new NullRequestCache()).and()
.formLogin().failureHandler(getRESTAuthenticationFailureHandler())
.successHandler(getRESTAuthenticationSuccessHandler()).usernameParameter("username")
.passwordParameter("password").and().exceptionHandling()
.authenticationEntryPoint(getRESTAuthenticationEntryPoint()).and()
//.addFilter(getAuthenticationFilter())
.csrf().disable();
}
@Bean
public HttpSessionStrategy httpSessionStrategy() {
return new HeaderHttpSessionStrategy();
}
@Bean
public RESTAuthenticationEntryPoint getRESTAuthenticationEntryPoint() {
return new RESTAuthenticationEntryPoint();
}
@Bean
public RESTAuthenticationSuccessHandler getRESTAuthenticationSuccessHandler() {
return new RESTAuthenticationSuccessHandler();
}
@Bean
public RESTAuthenticationFailureHandler getRESTAuthenticationFailureHandler() {
return new RESTAuthenticationFailureHandler();
}
@Bean
public AuthenticationFilter getAuthenticationFilter() {
AuthenticationFilter filter = new AuthenticationFilter();
try {
filter.setAuthenticationManager(this.authenticationManager());
} catch (Exception e) {
e.printStackTrace();
}
return filter;
}
public class RESTAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
public class RESTAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
clearAuthenticationAttributes(request);
}
}
public class RESTAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
super.onAuthenticationFailure(request, response, exception);
}
}
public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final Logger LOG = LoggerFactory.getLogger(AuthenticationFilter.class);
private boolean postOnly = true;
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = null;
String password = null;
UserDetails userDetails = null;
if ("application/json".equals(request.getHeader("Content-Type"))) {
userDetails = getJson(request);
if (userDetails != null) {
username = userDetails.getUsername();
}
} else {
username = obtainUsername(request);
}
if ("application/json".equals(request.getHeader("Content-Type"))) {
if (userDetails != null) {
password = userDetails.getPassword();
}
} else {
password = obtainPassword(request);
}
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
private UserDetails getJson(HttpServletRequest request) {
try {
final List<String> data = IOUtils.readLines(request.getReader());
final String jsonData = data.stream().collect(Collectors.joining());
LOG.info(jsonData);
UserDetails userDetails = objectMapper.readValue(jsonData, UserDetails.class);
return userDetails;
} catch (IOException e) {
LOG.error("Failed to read data {}", e.getMessage(), e);
return null;
}
}
}
}